mcrypt - what cipher to use?

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

User avatar
m@ndio
Forum Regular
Posts: 163
Joined: Fri Jun 06, 2003 12:09 pm
Location: UK

mcrypt - what cipher to use?

Post by m@ndio »

Hi I'm using mcrypt, what cipher should be used when encrypting / decrypting credit card details?? there are so many listed on php.net including:

MCRYPT_TWOFISH192

MCRYPT_TWOFISH256

MCRYPT_RC4

MCRYPT_3DES etc... etc...

what are the differences? do they have different levels of encryption?

8O
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

The OpenSSL O'Reilly book has a brief overview of the two-way ciphers and they recommend either RC4 or AES. Given their other comments, I think I would chose AES (they note that RC4 is hard to configure properly.). They also advise that your key be at least 80 bits long, this book was published in 2002, so that advice is probably still acceptable. (AES requires at least a 128 bit key so that should be plenty secure.)
m3rajk
DevNet Resident
Posts: 1191
Joined: Mon Jun 02, 2003 3:37 pm

Post by m3rajk »

also note that dod standards are rather outdated. they were created in the 60s/70s and never updated. 3DES is the latest way to do DES, the only one actually DOD approved.

there's benefits and drawbacks to every style. i may have taken a cryptology class in college, but this is clearly nielsene's feild. with what i've seen him post prevoiusly i expect he works in network and/or system security. when i asked about that stuff i noticed a few threads on the topic. the one that went and explained suggestions to people the most and also was able to give me the best understanging of how php works with it via his/her posts was nielsene
User avatar
Stoker
Forum Regular
Posts: 782
Joined: Thu Jan 23, 2003 9:45 pm
Location: SWNY
Contact:

Post by Stoker »

I am no cryptographer and dont know all the cibher terminology and that, but as far as I know, mcrypt is (mostly or only?) for symmetric encrypt/decrypt, meaning you encrypt with the same key you decrypt with... And that is not an acceptable method in any shared hosting or normal public webserver environment.. Basically, there must be no way of decrypting info on the webserver (unless it is in a proteced and controlled environment where keys are very safe etc etc)..

So most likely you want to use gnupg instead with your own private/public keypair, a PGP compatible method (PGP is a commercial software, that would work as well). Another free but lesser used alternative is to use OpenSSL with something like S/Mime and a x509 cert..

To safely use GPG your script should run suexec or cgiwrapped as your own user, the --homedir for the keyrings should not be the default .gnupg (paranoia), and file permissions should be as set by the gpg binary (on GNU/Linux and UNIX systems at least, windows is rarely safe anyway) when rings where created. NEVER ever should your private key have been transported by email or any other open transfer method, and it should ofcourse never have been on the server. If you only have Bill Gates machinery at home, I once upon a time wrote a short and unfinished intro to start using gpg here
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

Yes storing any secrets is dangerous on shared server. However, your database password is a secret and you store that on a shared server. The private key of a public-private key is stored on your server. So the public key method is no more secure than a secret key method....

Yes you can passphrase any key, but the passphrase must be stored somewhere. If its in your head only then the process can't be automated for the script. If its in the code somewhere, its on the server.
User avatar
Stoker
Forum Regular
Posts: 782
Joined: Thu Jan 23, 2003 9:45 pm
Location: SWNY
Contact:

Post by Stoker »

My whole point of using GPG is to never store the private key on the server.. There is no way that server side decryption is safe in any shared environment, nor on a standard webserver either, in my opinion..

If someone cracks the system and gets those numbers and VISA or MC asks you "How could they get the numbers?" , and I am surethey dont like answers like "It was so convenient to decrypt them on the server"..
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

Where are you suggesting to store the private key? If its not on the server what help is it in creating a solution for securely storing information? If you can only encrypt and not decrypt, why not just use a secure one-way hash?

Plus we don't know if the OP is on a shared server or not. We know from an earlier post that the OP has a secure webserver (SSL enabled), that often implies a non-shared environment. The database is apparently not on a secure server so it might be shared. If the webserver is dedicated there it is safe to store the secret (either shared secret for symmetric or private key for asymmetric).

How do you deal with your database connection information if you are against storing any secret on a shared host?
User avatar
Stoker
Forum Regular
Posts: 782
Joined: Thu Jan 23, 2003 9:45 pm
Location: SWNY
Contact:

Post by Stoker »

The server encrypts ans stores, you download the info to a local/protected workstation or server and decrypt there, preferably on a machine that is not networked at the time the private key is in use.. Read the GnuPG Privacy manual, it is very detailed about "best" practice.. "Best" may not always be practical, but storing the private key on a public server (or using symmetric) is way off and not very secure at all...

A stndard dedicated webserver box is to me not a whole lot more secure than a shared one, just less of a chance another user peeking in your files.. There are plenty of individual-account-SSL-enabled shared hosts out there.

On public servers I dont do anything in particular to protect a database key and such other than running scripts suexec/private if I can and ofcourse keeping all the login info outside the webroot, I do make sure that there are no sensitive data on there that can be decrypted if anyone gains access to it.. Name address email and phone etc is "private" as well, but the chance of great economical liability is much less than with info like account/cc numbers, ssn and other stuff like that.. If I where to host financial information like accounting or whatever, I would not do that on a shared server, I would use a dedicated hardened machine. If I wanted to use server side decryption I would probably go to rackspace and get a protected setup with a firewall and multiple machines where one is dedicated to handling the sensitive info and such, but most likely I would just get this type of service from someone else or consult with experts..
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

You raise some good points.

I'm used to an environment where I can completely control the webserver and database server machines. For me the webserver is as secure as I could make the "local/protected" machine.

However, I would also argue that using asymmetric encryption for "normal" use is a horrible inefficiency -- there are huge intialization costs and huge per encryption costs. Normally Public-Key is best used for the exchange of a secret key to use in future communications, not for actual encryption itself. I haven't seen any cryptographer who wasn't hawking his own algorithm promote public key over secret key universally -- and this is one of the classic cases for using symmetric algorithms.

It all comes down to the use cases of the developer. Why are CC# and other sensitive data being stored? How often is it needed to be accessed? How trusted/secure are the computers the data is stored and manipulated?

To me, if you're storing credit card number you had d*mn better well have a secure box handling the encryption, which to me means I can use a fast and secure algorithm.
User avatar
Stoker
Forum Regular
Posts: 782
Joined: Thu Jan 23, 2003 9:45 pm
Location: SWNY
Contact:

Post by Stoker »

Cost of disaster is difficult to measure :)

I do stay by my statement that anything that can be decrypted on the server is not safe, so any such use for shared environment is (to me) unsafe, on a dedicated machine it may be usable if precautions are taken..

As far as cost, I did a test on this and several machines in the past and found that up to 10 transactions per second is no big problem for any modern machine, but I never used this on any site that that generated more than 15-20GB/month in transfer and there is at peak times about 1 to 2 transactions per second (measured in 10 minute intervals).. This account was on a shared machine.

So to me the cost of gnupg VS mcrypt/3des is insignificant compared with the probability of someone being able to missuse the information if the server is compromised..

Here is the simple script I used to test the gpg time/resource consumption..

Code: Select all

<?php

  # (C) Copyright 2002 Jon T Stokkeland (Stoker)
  # Use at will - BCD / LGPL

  $gpg = '/usr/bin/gpg -ear certuser --batch --always-trust --no-secmem-warning --homedir /home/user/.somedir/ 2>&1';
  $count = 100;

  $start = explode(' ',microtime());

  while ($count--)
  {
    $num = md5(mt_rand());      # md5 hash generation and mt_rand  takes some time here too.. 
                                # a 32byte string to encrypt
    echo "\n\n".'Processing '.$num."\n";
    passthru ('/bin/echo '.$num.' | '.$gpg);
  }

  $end = explode(' ',microtime());
  echo "\n\n".'Started at '.date('r',$start[1]).'  .'.$start[0]."\n"
       .'Ended at '.date('r',$end[1]).'  .'.$end[0]."\n"
       .'Duration: '. ( ($end[0] + $end[1]) - ($start[0] + $start[1]) ) .' seconds'."\n\n";

?>

hehe this could probably be an forevergoing discussion of opionions :P

As long as the key is no safer than the data there is no poin in using encryption for storage at all!
Last edited by Stoker on Tue Jul 01, 2003 1:17 pm, edited 1 time in total.
User avatar
m@ndio
Forum Regular
Posts: 163
Joined: Fri Jun 06, 2003 12:09 pm
Location: UK

Post by m@ndio »

how good is the MCRYPT_RC6_256 method?
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

Its not listed in the book I have with me at work, so I'm not sure. If its like the other RC*'s, then its probably very good, but its also probably patented so it may not be free to use.
User avatar
m@ndio
Forum Regular
Posts: 163
Joined: Fri Jun 06, 2003 12:09 pm
Location: UK

Post by m@ndio »

hi nielsene.

MCRYPT_RC6_256 is listed on php.net here: http://uk2.php.net/manual/en/ref.mcrypt.php under mycrypt ciphers
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

Yes, but that doesn't provide any real details.

What is your anticipated volume? AES/3DES are rather slow, but they have had a huge amount of literature written about them. As a result they are thought to be more secure/conservative than the others. RC*s are often blindingly fast, not quite as understood, and at least two are patented. Blowfish is the fastest non-patented block cipher that is widely trusted.... Etc

I think I would use AES/3DES. If volume became a problem, it means you're doing weel enough to either afford extra servers or crypto-hardware accelerators.....
User avatar
Stoker
Forum Regular
Posts: 782
Joined: Thu Jan 23, 2003 9:45 pm
Location: SWNY
Contact:

Post by Stoker »

mandio, what will you be using it for and in what kind of environment? If you are having a shared account, and your scripts are world readable, your key is no safer than the data and there is no point in encrypting at all..
Post Reply