Skip to main content
Cryptography in Zend Framework 2



                                    Enrico Zimuel
                                    Senior PHP Engineer
                                    Zend Framework Team
                                    Zend Technologies




Uncon – 9th June, Dutch PHP Conference 2012
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)
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)
Supported algorithms
●
    Mcrypt: AES (Rijndael-128), Rijndael-192/256,
    Blowfish, Twofish, DES, 3DES, CAST-128/256,
    Saferplus, Serpent,
●
    OpenSSL: RSA, Diffie Hellman
●
    PBKDF2, Salted2SK
●
    Bcrypt
●
    Hash/HMAC functions provided by PHP: MD5, SHA-
    1/224/256/384/512, RIPEMD, TIGER, AVAL, ...
ZendCrypt components
●
    ZendCryptSymmetricMcrypt
●
    ZendCryptPublicKeyRsa
●
    ZendCryptPublicKeyDiffieHellman
●
    ZendCryptPassword
●
    ZendCryptKeyDerivation
●
    ZendCryptBlockCipher
●
    ZendCryptHash
●
    ZendCryptHmac
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
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);
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
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)
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
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
The bcrypt workload
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”;
}
}
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)
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
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
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
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”
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”
Thanks!
●
    Contacts:
     enrico@zend.com
     @ezimuel