Re: Credit Card Encryption

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Jason Gerfen wrote:
> Daniel Brown wrote:
>> On Dec 19, 2007 2:41 AM, Keith Spiller <larentium@xxxxxxxxxxxx> wrote:
>>> Ok I've done some research and some thinking.  What about storing orders in
>>> the database (product info and customer info) and then using GnuPG or PGP to
>>> send the credit card info to the merchant?  This way the credit card
>>> information is not stored on the server or in the database but only in
>>> printed format by the merchant.  Since my client processes all of the credit
>>> card orders by hand this seems like an ideal solution.
>>     I had a client that did offline (manual) processing of credit card
>> orders as well.  With liability issues and the problems that others
>> have already pointed out, storing the credit card information was not
>> an option, yet my client still needed some way of having the data
>> available offline.
> 
>>     Consider the following:
> 
>>     ISSUER                                LENGTH
>>     Diner's Club/Carte Blanche   14
>>     American Express                  15
>>     VISA                                      13 or 16
>>     MasterCard                            16
>>     Discover                                 16
> 
>>     Security checks aside (like making sure they selected the type of
>> card and that it matched the algorithm - VISA beginning with 4 and
>> being strlen($_POST['cardnum']) == 13 or 16, MasterCard being 16,
>> beginning with 51xx to 55xx, et cetera), I then had a hybrid of
>> storage and delivery.
> 
>>     Mail the first <? rand(4,6); ?> digits to the sales email
>> address(es) on file.  Three addresses on two domains were used for
>> redundancy in this case.  Store the remaining digits in the database.
>> You could write your own encryption algorithm or use one that is
>> publicly-available and reversible (Blowfish is what I was using, at
>> 128, key length of 56 lower ASCII characters, padded with 7 on the key
>> and four on the output - MD5, SHA1, et al are NOT options here).
> 
>>     The sales department then received the first digits of the credit
>> card number via email, which stated it was an order key.  Again, in my
> 
> Using the order number as the key is bad practice. Here is a random key
> generator that you could use for your public/private keys and still use
> the blowfish cipher as your method of encrypting:
> 
> <?PHP
> function ReadFolder( $folder )
> {
>  if( ( empty( $folder ) ) || ( !is_dir( $folder ) ) ) {
>   $rand_image = GenerateError( "Couldn't open directory" );
>  } else {
>   $rand_image = array();
>   if( $handle = opendir( $folder ) ) {
>    while( false !== ( $file = readdir( $handle ) ) ) {
>     if( $file != "." && $file != ".." && $file != "index.html" &&
> !is_dir( $file ) ) {
>      $rand_image[] = $file;
>     }
>    }
>    closedir( $handle );
>   }
>  }
>  return $rand_image;
> }
> 
> function MakeSuperRandom()
> {
>  return srand( ( double ) microtime( time() ) * 100000 );
> }
> 
> function PickRandomImages( $array )
> {
>  $num1 = count( $array );
>  $num1 = $num1 - 1;
>  MakeSuperRandom();
> 
>  $img_num = rand( 3, $num1 );
>  $image[] = $array[$img_num];
> 
>  $num2 = count( $array );
>  $num2 = $num2 - 1;
>  MakeSuperRandom();
> 
>  $img_num = rand( 3, $num2 );
>  $image[] = $array[$img_num];
> 
>  $num3 = count( $array );
>  $num3 = $num3 - 1;
>  MakeSuperRandom();
> 
>  $img_num = rand( 3, $num3 );
>  $image[] = $array[$img_num];
>  return $image;
> }
> 
> function ChkArray( $array )
> {
>  if( ( empty( $array ) ) || ( count( $array ) > 3 ) ) {
>   $data = 1;
>  } else {
>   $data = 0;
>  }
>  return $data;
> }
> 
> function GeneratePrivKey( $array )
> {
>  if( empty( $array ) ) {
>   $data = GenerateError( "Missing data for GeneratePrivKey function." );
>  } else {
>   for( $x = 0; $x < count( $array ); $x++ ) {
>    $keys[] = mhash( MHASH_SHA1, sha1( $array[$x] ) );
>   }
>   for( $y = 0; $y < count( $keys ); $y++ ) {
>    if( count( $keys ) == $keys[$y] ) {
>     $data .= $keys[$y];
>    } else {
>     $data .= $keys[$y] . ":";
>    }
>   }
>  }
>  return $data;
> }
> 
> function GeneratePubKey( $data )
> {
>  return md5( $data );
> }
> 
> function EncData( $data, $key )
> {
>  $td = mcrypt_module_open( 'rijndael-256', '', 'ofb', '' );
>  $iv = mcrypt_create_iv( mcrypt_enc_get_iv_size( $td ), MCRYPT_DEV_RANDOM );
>  $ks = mcrypt_enc_get_key_size( $td );
>  @mcrypt_generic_init( $td, $key, $iv );
>  $encrypted = mcrypt_generic( $td, $data );
>  echo "<br><b>Ciphered Text using Random Image Hash as Key:</b><pre> " .
> $encrypted . "</pre><br>";
>  @mcrypt_generic_deinit( $td );
>  @mcrypt_generic_init( $td, $key, $iv );
>  $decrypted = mdecrypt_generic( $td, $encrypted );
>  echo "<br><b>De-Ciphered Text using Random Image Hash as Key:</b><pre>"
> . $decrypted . "</pre>";
>  @mcrypt_generic_deinit( $td );
>  @mcrypt_module_close( $td );
> }
> 
> // to use functions
> $x = ReadFolder( "images/" );
> $y = PickRandomImages( $x );
> $b = GeneratePrivKey( $y );
> echo "<b>Private Key data:</b><pre>" . $b . "</pre>";
> $data = "<br>" . GeneratePubKey( $b );
> echo "<b>Public Key data:</b><pre>"; print_r( $data ); echo "</pre>";
> echo EncData( $credit_card_data, $b );
> 
> ?>
> 
> With that code you will have to re-write the 'EncData()' function to
> perform ONLY encryption as of right now it encrypts and decrypts for
> demonstration purposes only.
> 
> And on another note why not use a different delivery method altogether
> such as using java-script to encrypt the data prior to transmission,
> store the private key inside the local network, use the public key and
> associate it with the purchase within the database and develop a method
> of authentication for the users to retrieve the data and then, and only
> then use the private key to decrypt the data.
> 

My apologies, I just noticed you did mention a database for storage. SSL
would probably work better then java-script. Hell if you really wanted
to secure the data prior to transmission using flash might help obscure
the data and give you a good method of assigning a unique private/public
key as well as passing it through your cipher prior to transmission.

The kerberos authentication protocol does a similar method prior to
sending the data which is always the most secure against eves droppers
and man in the middle attacks.

> Just a thought.
> 
>> case, I wrote an algorithm that would encrypt these digits prior to
>> sending, using the actual order number as a key.  The accounting
>> software I wrote (all in PHP) would then retrieve the latter half of
>> the credit card number from the database, decrypt the first part of
>> the credit card number from the email (entered by the sales team on an
>> SSL-encrypted page), and the credit card number would be displayed in
>> full on the screen, to print, process, or verify.
> 
>>     The downside is that, if there are any problems with email and
>> delivery, the first $n digits of the card might not be received by the
>> sales department.  While, to date, I'm not aware of this having been a
>> problem for my client (knock on wood), it's still a possibility.  For
>> this reason, you need to be sure to either have the email address
>> confirmed prior to processing the order, or require a valid telephone
>> number, so that you can reach the customer in the event of a failure.
>> To assure the customer that you are calling legitimately, you will
>> still have the last digits of the credit card, as well as the
>> expiration data and CVV number (also stored in the database), the
>> billing address, and the date and time the order was placed.
> 
>>     It may not work for you, but that's how I created the system for
>> my client in 2004, and it's still being used today, with almost $8
>> Million in online sales.  [pats self on back]  ;-P
> 
>>     Now if I could just go back and renegotiate my contract for that gig....
> 
> 
> 

- --
Jason Gerfen

"I practice my religion
 while stepping on your
 toes..."
~The Ditty Bops
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFHaUaP5vk8bwKVAaIRAraBAKCFl/kkFJ9DCB4e3xF/MrOTQBxHbwCeP0mr
qMzidRdX+HQOsivTl83o9Lo=
=txPL
-----END PGP SIGNATURE-----

-- 
PHP Database Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [PHP Users]     [Postgresql Discussion]     [Kernel Newbies]     [Postgresql]     [Yosemite News]

  Powered by Linux