KEMBAR78
Cryptography with Zend Framework | PDF
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

Cryptography with Zend Framework

  • 1.
    Cryptography in ZendFramework 2 Enrico Zimuel Senior PHP Engineer Zend Framework Team Zend Technologies Uncon – 9th June, Dutch PHP Conference 2012
  • 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)
  • 4.
    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, ...
  • 5.
    ZendCrypt components ● ZendCryptSymmetricMcrypt ● ZendCryptPublicKeyRsa ● ZendCryptPublicKeyDiffieHellman ● ZendCryptPassword ● ZendCryptKeyDerivation ● ZendCryptBlockCipher ● ZendCryptHash ● ZendCryptHmac
  • 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; useZendCryptBlockCipher;     $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 storea 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 safelystore 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 ofbcrypt 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
  • 12.
  • 13.
    Check for validpasswords 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 “PBKDF2applies 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, useZendCryptKeyDerivationPbkdf2, 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 iterationswe 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 numbergenerator ● 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”
  • 20.
    Thanks! ● Contacts: enrico@zend.com @ezimuel