Found this code on phpbuilder website.
How secure and reliable is this code as long as the key is not revealed?
Any better encryption method which would be decryptable?

function x_Encrypt($string, $key)
{
  for($i=0; $i<strlen($string); $i++)
  {
    for($j=0; $j<strlen($key); $j++)
    {
      $string[$i] = $string[$i]^$key[$j];
    }
  }

  return $string;
}

function x_Decrypt($string, $key)
{
  for($i=0; $i<strlen($string); $i++)
  {
    for($j=0; $j<strlen($key); $j++)
    {
      $string[$i] = $key[$j]^$string[$i];
    }
  }

  return $string;
}

    First of all, because of a bug in the code you posted, it is pretty much the least secure encryption ever.

    Second of all, if you fix the bug, then you will have the most secure encryption ever as long as you only use a key once.

    If you are going to use the same key over and over, then you should discard this solution and use GPG. In fact, you should use GPG anyway since it's NEVER a good idea to build your own encryption tools.

      1) what is the bug in the code? please advice.

      2) and can you direct me to a standalone GPG encryption/decryption script that I can use?

        1) what is the bug in the code? please advice.

        Instead of XORing the bits of corresponding characters together, it XORs the bits from each character in the plaintext with each character in the key. In other words, you want a single loop, not nested loops.

        2) and can you direct me to a standalone GPG encryption/decryption script that I can use?

        What do you need the encryption for? Just blindly encrypting things does not necessary improve security.

          1) what is the bug in the code? please advice.

          If I tell you what the bugs are, do you promise not to use the script?

          There are two bugs, actually. First of all, a one time pad should apply the first byte of the key to the first byte of the string. The 2nd to the 2nd. 3-3. 4-4, etc. This code, since it nests the "for" loops, applies the first character of the key to the first character of the string, and then it applies the SECOND character of the key to the FIRST character of the string again. And then 3-1, 4-1, 5-1. So every single character of the key gets applied to the FIRST character of the string. And then every single character of the key gets applied to the SECOND character of the string. And then every single character of the key gets applied to the THIRD character of the string. In other words, the exact same procedure is being applied to every character in the string... and that's an encryption so simple to break that people play such games in the daily newspaper (without the use of a computer) for fun.

          The second bug is that the author seems to assume that $string[$i] is how you access each character in the string. I think he means, substr($string,$i,1). As it stands, he's refering to an array ($string[$i]) that doesn't even exist. The script won't even run like that.

          2) and can you direct me to a standalone GPG encryption/decryption script that I can use?

          The way I do it is to use exec to run a GPG command on the command line. Google for GPG tutorials. It will take you an hour or two to get the hang of it but it's time well spent because you will know the safest way to encrypt and decrypt content.

          The rule of thumb about security is that great programmers have already written excellent security tools, you might as well use them instead of writing your own and hoping that you don't make any mistakes. Since you're only a good programmer, you're likely unable to spot bugs in encryption software... it's much safer to rely on programs like GPG that were written by great programmers and then reviewed by other great programmers. It's true that there could still be a bug in GPG, but it's far more likely that there will be a bug in your own code - and worse, yet, since nobody reviews your code, you'll never know that the bug is there.

            The second bug is that the author seems to assume that $string[$i] is how you access each character in the string. I think he means, substr($string,$i,1). As it stands, he's refering to an array ($string[$i]) that doesn't even exist. The script won't even run like that.

            That's not a bug. That is correct. If the character is known to exist (i.e., $i is a valid index), then substr($string,$i,1) is a slow and obfuscated way of saying $string[$i].

              LaserLight is correct, there is only one bug in the script. But she really just illustrates my point: Average programmers like you and I shouldn't be writing/analyzing encryption scripts. We think we know what we're doing but our ignorance can let subtle mistakes slip by. Use GPG or similar. Better yet, consider Laserlight's question about why you need the encryption in the first place. Unless you use it according to a carefully designed security plan, it doesn't automatically increase security. (For example, a common mistake is to allow the decryption key to exist on your web server. If you're going to do that, then you might as well not have encryption in the first place).

                Hello,

                actually, my script has some username/passwords of external programs such as forums in its db for integration, for example if someone creates an account on my software, the software will create a forum account for the user too, so my software should have the db username and passowrd of the forum in its own db. Since this is not as sensitive as credit card number, I don't think it should be an issue to have the key hard coded in my sofware, as I will ionCube-encode it.

                also as I am going to give my software away for public download, not all servers can support exec, dl, pasthrou as server admin can disable these commands. so we have only two choices:
                1) a standalone GPG program which doesn't need exec, dl or so.
                2) fixing the bug of the script above. As you said a one time pad should apply the first byte of the key to the first byte of the string. so what about if the key doesn't have the same length as string? what you say, means key length and string length should be the same, but how will the script know what the length of the submitted string is, as the key is hard coded and might not have the same length as string?

                  there's plenty of encryption classes at phpclasses.org, just study one and see what it is doing

                    I need recommendation from experts here as I may choose a class which might have a bug like the code above, an expert please redirect me to the best class.

                      actually, my script has some username/passwords of external programs such as forums in its db for integration, for example if someone creates an account on my software, the software will create a forum account for the user too, so my software should have the db username and passowrd of the forum in its own db. Since this is not as sensitive as credit card number, I don't think it should be an issue to have the key hard coded in my sofware, as I will ionCube-encode it.

                      If that is the case, then perhaps do you not really need encryption at all. You might only need a good password hashing scheme. If the external scripts have sufficient security measures, you might not even need to do anything extra at all.

                      so what about if the key doesn't have the same length as string? what you say, means key length and string length should be the same, but how will the script know what the length of the submitted string is, as the key is hard coded and might not have the same length as string?

                      The plaintext length cannot be longer than the key length. If the key is longer, you can always just use some part of it. The problem with hardcoding the key is that it means you have a fixed key... so it is no longer a one time pad.

                        Somehow I too think this is a waste of time to encode the forums password in db, because if someone has the ability to hack the db of my software to get the password then he is indeed able to hack the config.php of the forums to get the password too. Isn't he?

                          Somehow I too think this is a waste of time to encode the forums password in db, because if someone has the ability to hack the db of my software to get the password then he is indeed able to hack the config.php of the forums to get the password too. Isn't he?

                          Ah, I missed that you were storing script administrator passwords. In that case you cannot hash them since that would be storing unusable data. Concerning an attacker obtaining the password: what the attacker is able to do depends on how the attacker managed to gain the information, so it is not automatically true that just because an attacker was able to get some information that he/she now has full access to all the information.

                            Yes, you got it now my script needs to have the passowrd of forums db to insert a user row externaly to forum db, now did you understand why I wanted to encode the password instead of hashing it? so now what do you recommend? storing them plain in my db, or will you redirect me to a usefull php block to encode the passowrd?

                              (EDIT: you guys said a bunch of stuff while I typed this so some of this is a repeat of what you already said).

                              I agree with Laserlight. You need to decide whether adding encryption will really help you. So far, you haven't said anything that suggests that encryption is going to add any security at all.

                              Saying, "Well, encryption is good, so I want encryption" isn't enough. Putting encryption on data and then putting the decryption key on your web server isn't enough. These don't add a little bit of security - they add zero security. You are wasting your time by adding the encryption.

                              You need to understand attack vectors. You need to choose a specific problem and find a way to prevent that problem. For example, if you owned a bank, you might decide that a vault is a good idea so you get one with 36 inch thick steel walls. But you need to get at the money so you put the key to the vault in the manager's desk drawer which is locked with a combination lock. Now, how secure is the vault? It's as secure as the desk is. If robbers come into the bank, they beat the manager until they find out where the key is (cut off the pinky, tell them the thumb is next). The wooden desk is one inch thick oak. Now it doesn't matter that the vault is 36 inch thick steel. So if you want to protect the money in the vault, the key has to be stored off site.

                              So back to your web site. Nobody can read from your database unless they SSH into your server. So some hacker breaks into your server, reads the database, looks for the decryption key, and decrypts the data in the database. You might as well have not even spent the time encrypting it. No security was gained by encrypting it.

                              So maybe you're saying to yourself, "Well I'm not trying to protect myself from a situation where someone SSH's into my server". That's good, we're half way there. What problem are you trying to protect yourself from? What scenario could happen where you could say, "It was a good thing that I encrypted the data in the database because the hackers got that far but were stumped and got nothing." ?

                              If encrypting your data isn't going to protect you, then it's not really going to matter much whether you're using good or bad encryption, is it?

                              If an expert in these forums directs you to the "best" class, it's as if they're saying that you should be using encryption - and so far, the only thing that I can see that encryption is going to give you is the ability to create a theater of security with a big Gee-Whiz factor to impress the managers who don't understand security.

                              On a different topic, if all you're going to be encrypting is passwords, you do realize that you don't need to decrypt them, right? You can MD5 them, put them in the database, and when someone tries to log into their account, you ask them their password and MD5 the answer. If it matches what's in the database, then they typed the right password.

                                I think the decision has to be made with the question: what happens if the passwords are obtained by an attacker? If the consequences are severe, then you have to think very carefully of security, i.e., akin to storing credit card numbers. If you can live with it after some damage control, then hardcoding a password into your ionCube encoded script and then using something like [man]mcrypt[/man] would suffice. If it does not really matter, then storing them in the clear would be perfectly okay.

                                  You can MD5 them, put them in the database, and when someone tries to log into their account, you ask them their password and MD5 the answer. If it matches what's in the database, then they typed the right password.

                                  Well, you did not understand what we are talking about. As I said the passowrd is a DB password of a forum, so it would not work if we use MD5. please read my previous posts to see what we are talking about. also if they can use SSH to get the password from DB then they can use SSH to get the password from config.php of forum rather than hacking DB of my software.

                                  then hardcoding a password into your ionCube encoded script and then using something like mcrypt would suffice.

                                  I knew about mcrypt, but what are other encryption/decryption methods? is there a good class on phpclasses.org that you can suggest me?

                                    I knew about mcrypt, but what are other encryption/decryption methods?

                                    mcrypt is a library, not a method. Why are you trying to avoid it?

                                    is there a good class on phpclasses.org that you can suggest me?

                                    I have not looked closely into the code provided at phpclasses.org so I cannot make any such suggestion.

                                      I don't avoid it personally, but as I am going to give my software away how about the user of my software doesn't have mcrypt installed on phpinfo() ? how much percentage of servers have it installed? the vast majority?

                                      well, may be I would forget about encoding forums password, because if everntually some gain access to DB via SSH to get it, then he has access to the config.php of forums too, this is why somehow I don't think encoding this password make sense? Am I not correct?

                                        I don't avoid it personally, but as I am going to give my software away how about the user of my software doesn't have mcrypt installed on phpinfo() ?

                                        That's a valid concern. One way out is to offer the user the option: if they have the mcrypt extension, it is used, otherwise it simply is not used.

                                        how much percentage of servers have it installed? the vast majority?

                                        Almost all the servers I have used had it installed, but then I was rather selective of my host, and in other cases I was running my own server or VPN so I could install it myself.

                                        well, may be I would forget about encoding forums password, because if everntually some gain access to DB via SSH to get it, then he has access to the config.php of forums too, this is why somehow I don't think encoding this password make sense? Am I not correct?

                                        It makes sense in the same way hashing passwords make sense: to protect the user in case the database is compromised. On the other hand, your users are expected to be community administrators, so they should know better than the average user that reusing passwords is risky.

                                          Write a Reply...