2. ZendCrypt
●
ZendCrypt is a new component of ZF2
(>= 2.0.0beta4)
●
Facilitates the usage of cryptography in PHP
projects
●
Supports strong cryptography (standards +
best practices)
3. ZendCrypt: main features
●
Symmetric encryption/decryption +
authentication
●
Public key cryptography
●
Key Derivation Function (PBKDF2, Salted2SK)
●
Secure password hashing (bcrypt)
●
Hash
●
Hash-based Message Authentication Code
(HMAC)
6. Encryption + authentication
●
ZendCryptBlockCipher
●
Default:
– AES encryption in CBC mode
– HMAC authentication (SHA-256)
– Random IV for each encryption
– PKCS7 padding (RFC 5652)
– PBKDF2 for key derivation (encrypt and auth)
– Prevent timing attacks
7. Example: encrypt/decrypt
use ZendCryptBlockCipher;
use ZendCryptBlockCipher;
$cipher = BlockCipher::factory('mcrypt',
$cipher = BlockCipher::factory('mcrypt',
array('algorithm' => 'aes')
array('algorithm' => 'aes')
);
);
$cipher->setKey('this is the encryption key');
$cipher->setKey('this is the encryption key');
$text
$text = 'This is the message to encrypt';
= 'This is the message to encrypt';
$encrypted = $cipher->encrypt($text);
$encrypted = $cipher->encrypt($text);
printf("Encrypted text: %sn", $encrypted);
printf("Encrypted text: %sn", $encrypted);
$text
$text = $cipher->decrypt($encrypted);
= $cipher->decrypt($encrypted);
printf("Decrypted text: %sn", $text);
printf("Decrypted text: %sn", $text);
8. Encryption format
Encryption = HMAC . IV . ENCRYPT
●
MSG is the message to encrypt
●
KEY is the encryption key (by PBKDF2)
●
AUTH is the authentication key (by PBKDF2)
●
ENCRYPT = AES(MSG, KEY)
●
HMAC = HMAC('sha256', AUTH, 'AES' . IV . ENCRYPT)
●
IV = random
9. How to store a password?
●
“More than 6 million LinkedIn passwords
stolen” 7th July 2012, cnnmoney.com
●
Don't use only an hash algorithm (dictionary
attacks)
●
Even using a salt is insecure (brute force
attacks)
10. How to safely store a password
●
bcrypt is an adaptive cryptographic hash
function for passwords
●
It's considered secure because is slow
(prevent dictionary attacks)
●
Implemented using crypt() of PHP
●
It uses a parameter, the workload (or cost)
that specify the amount of work
●
More work means more secure hash value
11. Example: usage of bcrypt
use ZendCryptPasswordBcrypt;
use ZendCryptPasswordBcrypt;
$bcrypt
$bcrypt = new Bcrypt();
= new Bcrypt();
$password = $bcrypt->create('password');
$password = $bcrypt->create('password');
printf ("Password: %sn", $password);
printf ("Password: %sn", $password);
●
The output ($password) is a string of 60 bytes
●
The default value of the working factor is 14
13. Check for valid passwords
use ZendCryptPasswordBcrypt;
use ZendCryptPasswordBcrypt;
$bcrypt
$bcrypt = new Bcrypt();
= new Bcrypt();
$password = $_POST['password'];
$password = $_POST['password'];
$hash
$hash = '…'; // i.e. get from a database
= '…'; // i.e. get from a database
if ($bcrypt->verify($password, $hash)) {
if ($bcrypt->verify($password, $hash)) {
echo “The password is valid”;
echo “The password is valid”;
} else {
} else {
Echo “The password is not valid”;
Echo “The password is not valid”;
}
}
14. Key Derivation Function
●
NEVER USE user's password as crypto key!
●
Key Derivation Function generates
cryptographic keys based on user's
passwords
●
PBKDF2 is a KDF (RFC 2898, PKCS #5 v2.0)
15. PBKDF2
“PBKDF2 applies a pseudorandom function,
such as a cryptographic hash, cipher, or HMAC
to the input password or passphrase along with
a salt value and repeats the process many times
to produce a derived key, which can then be
used as a cryptographic key in subsequent
operations. The added computational work
makes password cracking much more difficult,
and is known as key stretching” From Wikipedia
16. Example: Pbkdf2
use ZendCryptKeyDerivationPbkdf2,
use ZendCryptKeyDerivationPbkdf2,
ZendMathMath;
ZendMathMath;
$salt = Math::randBytes(32);
$salt = Math::randBytes(32);
$pass = 'this is the password of the user';
$pass = 'this is the password of the user';
$hash = Pbkdf2::calc('sha256', $pass, $salt, 10000, 32);
$hash = Pbkdf2::calc('sha256', $pass, $salt, 10000, 32);
●
It generates a crypto key of 32 bytes using
SHA-256 + random salt with an interation of
10'000 times
17. How many iterations we need?
●
It depends on the CPU power that you use
●
Suggestion: use at least 1 sec. of computation
●
Using an Intel Core i5 CPU at 3.3Ghz you need
at least 100’000 iterations to get about 1 sec.
of computation
18. ZF2 random number generator
●
ZendMathMath::randBytes($length, $strong = false)
●
ZendMathMath::rand($min, $max, $strong = false)
●
Fallback strategy:
1) If OpenSSL: openssl_random_pseudo_bytes()
2) If Mcrypt: mcrypt_create_iv()
3) If (!$strong): mt_rand()
4) else throwing exception “Cannot generate
strong random numbers”
19. Some references
●
Niels Ferguson, Bruce Schneier, and Tadayoshi Kohno “
Cryptography Engineering” John Wiley & Sons, 2010
●
Dan Boneh, Cryptography Course, Stanford University,
Coursera free online courses
●
Coda Hale, How to safely store a password
●
Zend Framework 2
●
Anthony Ferrara, PHP-CryptLib
●
E.Zimuel “Cryptography in PHP” Web & PHP Magazine, Issue
2/2012
●
E.Zimuel “Cryptography made easy with Zend Framework”