Hi.
I want to encrypt some data i get on a site and send it through email to my client who is supposed to decrypt it. How do i do that?

I have no idea about encryption and after a little search i found gnuPG and its GUI for windows WinPT, which generates keys, encrypts, decrypts, etc.

Is mcrypt() used for this purpose? By the way, on my windows development machine, i don't have mcrypt.

In general, i'd be very obliged if someone guide me through the whole procedure of using a key on the server, encrypt data and decrypt it on my client's side.

Thanks,
John

    Heres a function that I modified from a RC4 script found at http://www.xs4all.nl/~cg/ciphersaber/ This version is written a little better then the version by Ian Gulliver, and it is better fit for text because of the base64 decode, and the serialize feature is also nice in some scenarios. But the script by Ian Gulliver can binary files(I think) were mine was made with plaintext encryption in mind.

    <edit>mcrypt is no good, it can only encypt upto 400 chars</edit>

    <?php
    
    # Copyright (c) 2003 [email]jasonlester@lycos.co.uk[/email]                                                
    
    # This program is free software. You can redistribute it and/or modify 
    # it under the terms of the GNU General Public License as published by 
    # the Free Software Foundation; either version 2 of the License.     
    
    # ARCFOUR stream cipher encryption algorithm with CipherSaber-2 modification. 
    
    # ARCFOUR (aka RC4) is an industry standerd for strong encryption, and is aclaimed as an industry leader in performance.
    # To vouch for its stregth, products such as Microsoft Terminal Server, Microsoft CryptoAPI 2.0 for Windows Server 2003 and Oracle9 databse 
    # with Oracle Advanced Security use the RC4 encryption algorithm. 
    
    # For information on ARCFOUR goto [url]http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt[/url]
    
    # ARC4() works as follows: ARC4( $data, $pass, "Action");
    # The "action" is what you want ARC4 to do:
    #  action "e-1" - Encrypt data with ARC4.
    # 		It is used like this: ARC4( $data, $pass, "e-1");
    #  action "d-1" - Decyrpt data encrypted by action e-1.
    # 		It is used like this: ARC4( $data, $pass, "d-1");
    #  action "e-2" - Encrypt data with ARC4 and then base64 encode encrypted data.
    # 		It is used like this: ARC4( $data, $pass, "e-2");
    #  action "d-2" - base64 decode and then decrypt data.
    # 		It is used like this: ARC4( $data, $pass, "d-2");
    #	action "e-3" - Serialize input, Encrypt data with ARC4 and then base64 encode encrypted-serialized data.
    # 		It is used like this: ARC4( $data, $pass, "e-3");
    #  action "d-3" - base64 decode, decrypt and then unserialize data.
    # 		It is used like this: ARC4( $data, $pass, "d-3");
    
    # $ivcl sets the character length of the initialization vector. The larger the better, but for security reasons the pass phrease shoud be 4-5 times
    # LARGER then the IV. With a IV of ten (default) your pass should be 40-50 characters in length, or around 10-15 words. But this is only for
    # MAX security. The more you vear away from it the less secure the encyption will be, but the importance of your encryption is only as
    # important as what your encrypting, so you can be the judge.
    
    function ARC4($p, $d, $action)
    {	$ivcl= 10;
    	$N = 1;
    	static $randset = 0;
    	if($action == "d-1")
    	{	$k = substr($d, 0, $ivcl);
    		$d = substr($d, $ivcl);
    	}
    	elseif($action == "d-2" || $action =="d-3")
    	{	$d = base64_decode($d);
    		$k = substr($d, 0, $ivcl);
    		$d = substr($d, $ivcl);
    	}
    	elseif($action == "e-1" || $action == "e-2" || $action == "e-3")
    	{	$k="";
    		if($ivcl>0)
    		{	while(strlen($k)<$ivcl)
    			{	switch(mt_rand(1,3))
    				{
    				case 1:
    					$k.=chr(mt_rand(48,57));
    				break;  
    case 2: $k.=chr(mt_rand(65,90)); break; case 3: $k.=chr(mt_rand(97,122)); break; } } } } if($action == "e-3") { $d = serialize($d); } $p .= $k; for ($i=0; $i < 255; $i++) $S[$i] = $i; $j = 0; $t = strlen($p); for ($i=0; $i < 255; $i++) { $K[$i] = ord(substr($p,$j,1)); $j = ($j + 1) % $t; } $j=0; for ($kk=0; $kk < $N; $kk++) { for ($i = 0; $i < 255; $i++) { $j = ($j + $S[$i] + $K[$i]) & 0xff; $t = $S[$i]; $S[$i] = $S[$j]; $S[$j] = $t; } } $i=0; $j=0; $ii=0; $ret = ''; $dlen = strlen($d); for ($ii=0; $ii < $dlen; $ii++) { $c=$d{$ii}; $i = ($i + 1) & 0xff; $j = ($j + $S[$i]) & 0xff; $t = $S[$i]; $S[$i] = $S[$j]; $S[$j] = $t; $t = ($S[$i] + $S[$j]) & 0xff; $ret .= chr($S[$t]) ^ $c; } if($action == "d-1" || $action == "d-2") { return $ret; } elseif($action == "d-3") { $ret = unserialize(stripslashes($ret)); return $ret; } elseif($action == "e-1") { return $k .= $ret; } elseif($action == "e-2" || $action == "e-3") { return base64_encode($k .= $ret); } }

      did you catch this section

      http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt

      It must be strongly recommended that no two plaintexts are encrypted
      with the same key. Otherwise the plaintext can usually be broken, and
      often even quite easily. If the two encrypted messages are XORed
      together, the result is the XOR of the original plaintexts. Given the
      encrypted messages are text strings, credit card numbers, or other
      byte streams with some known properties, the plaintexts can be
      estimated with great accuracy. See the [DAWSON AND NIELSEN] for more
      details.

      maybe not the best encryption algorithm for creditcard numbers and or like plain text messages...

      what am i missing that makes this algorithm useful... im interested in figuring this out so tell me where im confused

        Originally posted by ednark
        did you catch this section

        http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt



        maybe not the best encryption algorithm for creditcard numbers and or like plain text messages...

        what am i missing that makes this algorithm useful... im interested in figuring this out so tell me where im confused

        The IV (initialization vector) is a randomly generated string which is used with your pass phrase during encryption. Because of the randomly generated IV, your passphrase is never exactly the same. The IV is stored un-encrypted in the first x charecters of the message (x is the char leghth of the IV set by $ivcl) and is removed and used along with the pass phrase to decrypt the data. Goto http://ciphersaber.gurus.com/cryptanalysis.html for more information.

        Also note that this function has the CipherSaber-2 modifaction. See the link above.

          Don't you have a link that's a little more current? 🙂

          INTERNET-DRAFT
          14 July 1999
          Expires: 17 December 1999

          Internet-Drafts are draft documents valid for a maximum of six
          months and may be updated, replaced, or obsoleted by other
          documents at any time. It is inappropriate to use
          Internet-Drafts as reference material or to cite them other
          than as "work in progress."

            Originally posted by Weedpacket
            Don't you have a link that's a little more current? 🙂

            http://www.rsasecurity.com/rsalabs/faq/3-6-3.html

            RC4 has been around for a while, but the bugs have been worked out as needed. Though it might not be the most secure thing out there, many trusted apps use it. Its also used in SSL.

              don't want to be too picky but...

              if you are storing the key with the encrypted info... can't someone just decode it on the fly as long as they know the algorithm you are using?

              or is the secrecy of the specific code used enough to make this safe (assuming you didn't post your exact algorithm here a few posts ago)?

              [PS]

              i thought with pgp encryption schemes the key is passed once during the initial handshake sequence only, and used throughout the process. here it seems you are sending the key across with each transaction, which could be dangerous? what am i missing

                <edit>miss read you question</edit> It hasent been known to be a problem.

                  All algorithms have there critics, which is good because you should know all of the possible risks
                  before you decide to depend on something for security. But many of these critics will never trust
                  anything to be "truly" secure (I wont argue with that). I wont argue about the assorted theories either
                  because many of them go beyond my knowledge, but hundreds of realworld test have been done on RC4
                  and only a couple of the theories have proven to be affective attacks against RC4(These have been fixed).
                  There are other algorithms that are considered to be more secure by the hardcore crypto buffs,
                  but they come with a cost (mcrypt will only encrypt up to 400 bytes to keep your script
                  from timing out, where RC4 runs transparently at 400 bytes, I have tested it at 100,000 bytes(17,981 words)).
                  You can also use OpenSSL to encrypt data and store it locally if you have the OpenSSL module compiled
                  with php, but that's sort of like comparing apples to apples since RC4 meets SSL security standards.
                  Overall RC4 is considered secure for data transfer and storage(which is why it has been excepted by
                  SSL standards) but there are better alternatives if you dont find RC4 to be good for your needs.

                  Enjoy the script if you like 🙂

                    Originally posted by ednark
                    if you are storing the key with the encrypted info... can't someone just decode it on the fly as long as they know the algorithm you are using?

                    As the German military discovered to their cost in World War II, no encryption scheme can be considered "secure" until it has been published and found by the wider community to be suitably resistant to attack - open source in other words.
                    The motivation behind modern encryption algorithms such as Blowfish, Rijndael, etc., as well as message digest algorithms such as MD5 and SHA1, is that they are extremely difficult to "reverse"; in (literally) the same way that multiplying two huge numbers together is easy compared to the reverse operation of taking one huge number and factorising it.

                    The rider of course is that if you don't know the algorithm being used you can't have any confidence in it. Many are the times that software vendors have modified existing encryption algorithms in some closed proprietary fashion (through convenience of implementation, or to lock customers in to using their product or whatever) only to create gaping security flaws in the process.

                      ok i went back to looking at rc4 today and figured it out.

                      i was confused earlier, i was under the impression that you were appending the entire key used for the encryption along with each message. after reworking the variable names of the algorithm into english it became clear that you were only adding the initialization vector, which i am much more comfortable with.

                      here is my slight reworking of your code, added in some switch statements instead of elsif, made your substr calls into $string{$index} calls, and changed the e-1 and the varibale names into more descriptive english

                      it was my execrise to understand the algorithm and not an admonishment of JLerster's coding abilities, but i'll post it here for anyone else.

                      <?php
                      
                      $enc = arcfour( 'encryptme', 'thisisasuperduperpassword', array( 'action'=>'enc', 'passes'=>3, 'init_vector_len'=>20 ) );
                      for ( $i=0; $i<strlen($enc); $i++ ) {
                          echo $enc{$i}.":".ord($enc{$i})."<br />\n";
                      }
                      
                      function arcfour( $data, $password, $options=array() )
                      {
                          $init_vector_len = 10;
                          $passes = 1;
                          $action = 'enc';
                      
                      if ( !empty($options) ) {
                          extract( $options );
                      }
                      
                      switch( $action ) {
                          case 'enc':
                          case 'enc_64':
                          case 'enc_serial':
                              $init_vector = '';
                              if( $init_vector_len > 0 ) {
                                  while(strlen($init_vector)<$init_vector_len) {
                                      switch(mt_rand(1,3)) {
                                         case 1:
                                              $init_vector .= chr(mt_rand(48,57));
                                              break;  
                                          case 2:
                                              $init_vector .= chr(mt_rand(65,90)); 
                                              break; 
                                          case 3: 
                                              $init_vector .= chr(mt_rand(97,122)); 
                                              break;
                                      } # switch
                                  } # while 
                                  if ( $action == 'enc_serial' ) {
                                      $data = serialize($data);
                                  }
                              } # if
                              break;
                          case 'dec':
                              $init_vector = substr($data, 0, $init_vector_len);
                              $data = substr($data, $init_vector_len);
                              break;
                          case 'dec_64':
                          case 'dec_serial':
                              $data = base64_decode($data);
                              $init_vector = substr($data, 0, $init_vector_len);
                              $data = substr($data, $init_vector_len);
                              break;
                      } # switch
                      
                      $password .= $init_vector;
                      
                      for ($i=0; $i < 255; $i++)
                          $state[$i] = $i;
                      
                      $password_index = 0;
                      $password_len = strlen($password);
                      
                      for ($key_index=0; $key_index < 255; $key_index++) {
                          $key[$key_index] = ord($password{$password_index});
                          $password_index = ($password_index + 1) % $password_len;
                      }
                      
                      $index2 = 0;
                      for ($counter=0; $counter<$passes; $counter++) {
                        for ($index = 0; $index < 255; $index++) {
                              $index2 = ($index2 + $state[$index] + $key[$index]) & 0xff;
                              $temp = $state[$index];
                              $state[$index] = $state[$index2];
                              $state[$index2] = $temp;
                          }
                      }
                      
                      $encrypted = '';
                      $data_len = strlen($data);
                      
                      $index2 = 0;
                      $index3 = 0;
                      
                      for ($index=0; $index < $data_len; $index++) {
                          $index2 = ($index2 + 1) & 0xff;
                          $index3 = ($index3 + $state[$index2]) & 0xff;
                          $index4 = $state[$index2];
                          $state[$index2] = $state[$index3];
                          $state[$index3] = $index4;
                          $index4 = ($state[$index2] + $state[$index3]) & 0xff;
                          $encrypted .= chr($state[$index4]) ^ $data{$index};
                      }
                      
                      switch( $action ) {
                          case 'dec':
                          case 'dec_64':
                              return $encrypted;
                              break;
                          case 'dec_serial':
                              return unserialize(stripslashes($encrypted));
                              break;
                          case 'enc':
                              return $init_vector.$encrypted;
                              break;
                          case 'enc_64':
                          case 'enc_serial':
                              return base64_encode($init_vector.$encrypted);
                              break;
                      
                      }
                      } 
                      
                      ?>
                      
                        a month later

                        I occasionally get a warning about the offset 255 being out of range (is this something to worry about)

                        for ($kk=0; $kk < $N; $kk++)
                        { for ($i = 0; $i < 255; $i++)
                        { $j = ($j + $S[$i] + $K[$i]) & 0xff;
                        $t = $S[$i];
                        $S[$i] = $S[$j]; // warning here
                        $S[$j] = $t;

                          Write a Reply...