Security is a very important aspect of web applications. In order to protect sensitive data we should use cryptography. But cryptography means security? Absolutely not, especially if developers do not,especially if developers do not use it properly. In this talk I would like to present some best practices in PHP to implement secure cryptography using the extensions mcrypt, Hash and OpenSSL.
2. About me
October 2011
• Enrico Zimuel (ezimuel)
• Software Engineer since 1996
– Assembly x86, C/C++, Java, Perl, PHP
• Enjoying PHP since 1999
• Senior PHP Engineer at Zend
Technologies since 2008
• Author of two italian books about
Email: enrico@zend.com
applied cryptography
• B.Sc. Computer Science and
Economics from University of
Pescara (Italy)
3. Summary
October 2011
● Cryptography in PHP
● Some use cases:
● Safe way to store passwords
● Generate pseudo-random numbers
● Encrypt/decrypt sensitive data
● Demo: encrypt PHP session data
5. crypt()
October 2011
● One-way string hashing
● Support strong cryptography
● bcrypt, sha-256, sha-512
● PHP 5.3.0 – bcrypt support
● PHP 5.3.2 – sha-256/512
● Note: don't use PHP 5.3.7 (bug #55439)
6. Mcrypt
October 2011
● Mcrypt is an interface to the mcrypt library
● Supports the following encryption algorithms:
● 3DES, ARCFOUR, BLOWFISH, CAST, DES,
ENIGMA, GOST, IDEA (non-free), LOKI97,
MARS, PANAMA, RIJNDAEL, RC2, RC4,
RC6, SAFER, SERPENT, SKIPJACK, TEAN,
TWOFISH, WAKE, XTEA
7. Hash
October 2011
● Enabled by default from PHP 5.1.2
● Hash or HMAC (Hash-based Message
Authentication Code)
● Supported hash algorithms: MD4, MD5,
SHA1, SHA256, SHA384, SHA512,
RIPEMD, RIPEMD, WHIRLPOOL, GOST,
TIGER, HAVAL, etc
8. OpenSSL
October 2011
● The OpenSSL extension uses the functions of
the OpenSSL project for generation and
verification of signatures and for sealing
(encrypting) and opening (decrypting) data
● Public key cryptography (RSA algorithm)
9. Which algorithm?
October 2011
● Some suggestions:
● Symmetric encryption:
– Blowfish / Twofish
– Rijndael (AES, FIST 197 standard
since 2001)
● Hash: SHA-256, 384, 512
● Public key: RSA
10. Cryptography vs. Security
October 2011
● Cryptography doesn't mean security
● Encryption is not enough
● Bruce Schneier quotes:
● “Security is only as strong as the
weakest link”
● “Security is a process, not a product”
13. Use case 1: store a password
October 2011
● Scenario:
● Web applications with a protect area
● Username and password to login
● Problem: how to safely store a password?
14. Hash a password
October 2011
● Basic ideas, use of hash algorithms:
● md5($password) – not secure
– Dictionary attack (pre-built)
● md5($salt . $password) – better but still insecure
– Dictionary attacks:
● 700'000'000 passwords a second using CUDA (budget
of 2000 $, a week)
● Cloud computing, 500'000'000 passwords a second
(about $300/hour)
15. bcrypt
October 2011
● Better idea, use of bcrypt algorithm:
● bcrypt prevent the dictionary attacks
because is slow as hell
● Based on a variant of Blowfish
● Introduce a work factor, which allows you to
determine how expensive the hash function
will be
16. bcrypt in PHP
October 2011
● Hash the password using bcrypt (PHP 5.3+)
$salt = substr(str_replace('+', '.',
$salt = substr(str_replace('+', '.',
base64_encode($salt)), 0, 22);
base64_encode($salt)), 0, 22);
$hash = crypt($password,'$2a$'.$workload.'$'.$salt);
$hash = crypt($password,'$2a$'.$workload.'$'.$salt);
●
$salt is a random string (it is not a secret!)
●
$workload is the bcrypt's workload (from 10 to 31)
18. bcrypt output
October 2011
● Example of bcrypt's output:
$2a$14$c2Rmc2Fka2hmamhzYWRmauBpwLLDFKNPTfmCeuMHVnMVaLatNlFZO
● c2Rmc2Fka2hmamhzYWRmau is the salt
● Workload: 14
● Length of 60 btyes
19. bcrypt authentication
October 2011
● How to check if a $userpassword is valid
for a $hash value?
if ($hash==crypt($userpassword,$hash)) {
if ($hash==crypt($userpassword,$hash)) {
echo 'The password is correct';
echo 'The password is correct';
} else {
} else {
echo 'The password is not correct!';
echo 'The password is not correct!';
}}
20. Use case 2: generate random
data in PHP
October 2011
● Scenario:
● Generate random passwords for
– Login systems
– API systems
● Problem: how to generate random data
in PHP?
22. PHP vs. randomness
October 2011
● How generate a pseudo-random value in PHP?
● Not good for cryptography purpose:
● rand()
● mt_rand()
● Good for cryptography (PHP 5.3+):
● openssl_random_pseudo_bytes()
23. rand() is real random?
October 2011
Pseudo-random bits rand() in PHP on Windows
From random.org website
24. Use case 3: encrypt data
October 2011
● Scenario:
● We want to store some sensitive data
(e.g. credit card numbers)
● Problem:
● How to encrypt this data in PHP?
25. Symmetric encryption
October 2011
● Using Mcrypt extension:
●
mcrypt_encrypt(string $cipher,string $key,
string $data,string $mode[,string $iv])
●
mcrypt_decrypt(string $cipher,string $key,
string $data,string $mode[,string $iv])
● What are these $mode and $iv parameters?
26. Encryption mode
October 2011
● Symmetric encryption mode:
● ECB, CBC, CFB, OFB, NOFB or STREAM
● We are going to use the CBC that is the most
used and secure
● Cipher-Block Chaining (CBC) mode of operation
was invented in 1976 by IBM
27. CBC
October 2011
The Plaintext (input) is divided into blocks
Block 1 Block 2 Block 3
...
Block 1 Block 2 Block 3
The Ciphertext (output) is the concatenation of the cipher-blocks
28. IV
October 2011
● Initialization Vector (IV) is a fixed-size input that
is typically required to be random or pseudo
● The IV is not a secret, you can send it in
plaintext
● Usually IV is stored before the encrypted
message
● Must be unique for each encrypted message
29. Encryption is not enough
October 2011
● We cannot use only encryption to store sensitive
data, we need also authentication!
● Encryption doesn't prevent alteration of data
● Padding Oracle Attack (Vaudenay, EuroCrypt 2002)
● We need to authenticate:
● MAC (Message Authentication Code)
● HMAC (Hash-based Message Authentication
Code)
30. HMAC
October 2011
● In PHP we can generate an HMAC using the
hash_hmac() function:
hash_hmac ($algo, $msg, $key)
$algo is the hash algorithm to use (e.g. sha256)
$msg is the message
$key is the key for the HMAC
31. Encryption + authentication
October 2011
● Three possible ways:
● Encrypt-then-authenticate
● Authenticate-then-encrypt
● Encrypt-and-authenticate
● We will use encrypt-then-authenticate,
as suggested by Schneier in [1]
32. Demo: encrypt session data
October 2011
● Specific PHP session handler to encrypt
session data using files
● Use of AES (Rijndael 128) + HMAC (SHA-256)
● Pseudo-random session key
● The encryption and authentication keys are
stored in a cookie variable
● Source code:
https://github.com/ezimuel/PHP-Secure-Session
33. Conclusion (1)
October 2011
● Use standard algorithms for cryptography:
● AES (Rijndael 128), SHA-* hash family, RSA
● Generate random data using the function:
● openssl_random_pseudo_bytes()
● Store passwords using bcrypt:
● crypt($password, '$2a$'.$workload.'$'.$salt)
34. Conclusion (2)
October 2011
● For symmetric encryption:
● Use CBC mode with a different random IV
for each encryption
● Always authenticate the encryption data
(using HMAC): encrypt-then-authenticate
● Use HTTPS (SSL/TLS) to protect the
communication client/server
35. References
October 2011
(1) N. Ferguson, B. Schneier, T. Kohno, “Cryptography
Engineering”, Wiley Publishing, 2010
(2) Serge Vaudenay, “Security Flaws Induced by CBC Padding
Applications to SSL, IPSEC, WTLS”, EuroCrypt 2002
● Web:
● PHP cryptography extensions
● How to safely store a password
● bcrypt algorithm
● SHA-1 challenge
● Nvidia CUDA
● Random.org
36. Thank you!
October 2011
● Vote this talk:
● http://joind.in/3748
● Comments and feedbacks:
● enrico@zend.com