Cryptography
       In PHP
For The Average Developer
Cryptography
● Keeping Data Secure
  ○ Safe From Viewing
  ○ Safe From Tampering
  ○ Safe From Forgery
● Not A Silver Bullet
  ○ XSS
  ○ SQLI
  ○ Social Engineering
● Very Hard To Do
  ○ Any bug will cause problems
The First Rule
of Cryptography
Don't Do It!
Leave It
  For
Experts
Random!
The Foundation of Cryptography

● Classified Under Three Types:
  ○ Weak
    ■ For non-cryptographic usages
  ○ Strong
    ■ For cryptographic usages where security does
       not depend on the strength of randomness
  ○ Cryptographically Secure
    ■ For cryptographic usage when security does
       depend on the strength of randomness
Vulnerabilities of
           Randomness
● Bias
  ○ Certain values tend to occur more often making it
    easier to predict future numbers
● Predictability
  ○ Knowing past numbers helps predict future
    numbers
● Poisoning
  ○ Ability to alter future random number generation
Weak Random in PHP
Not to be used for cryptographic usages!!!

●   rand()
●   mt_rand()
●   uniqid()
●   lcg_value()
Strong Random in PHP
●   mcrypt_create_iv()
    ○ MCRYPT_DEV_URANDOM

● openssl_random_pseudo_bytes()


●   /dev/urandom
    ○ For *nix systems only
Cryptographically Secure
●   mcrypt_create_iv()
    ○ MCRYPT_DEV_RANDOM

● openssl_random_pseudo_bytes()
  ○ Maybe

●   /dev/random
    ○ For *nix systems only
NEVER
 Use Weak
For Security
NEVER
 Use CS
When Not
 Needed
If In Doubt
 Use Strong
Randomness
Encryption vs Hashing
● Encryption
  ○ Encoding
  ○ 2 Way / Reversible
  ○ Putting a lock on a box
● Hashing
  ○ Signing
  ○ 1 Way / Non-Reversible
  ○ Taking a person's finger-print
Encryption
Seriously,
Don't Do It!
Terms
● Key
  ○ Secure string of data


● Plain-Text
  ○ The text you want to keep secret


● Cipher-Text
  ○ The encrypted output
Two Basic Types
● Symmetric Encryption
  ○ Like a Pad-Lock with a shared key
  ○ The only secret is the key
  ○ Both sides must have the same key
● Asymmetric Encryption
  ○ Like a pair of Pad-Locks
    ■ The "lock" is the public key
  ○ The only secret is the private key
  ○ Both sides have their own key
Symmetric Encryption 101
● Number:
  01

Scratch That

● Numbers:
  01 04 01 54 95 42 64 12
Symmetric Encryption 101
 Let's Add A "Secret" Number!


01 04 01 54 95 42 64 12

+10

11 14 11 64 05 52 74 22
Secret Numbers
● We just invented the Caesar Cipher
  ○ Commonly known as "ROT13"


● But There Are Problems:
  ○ Vulnerable To Statistical Attacks
  ○ Vulnerable To Brute Forcing
    ■ Only 100 possible secret numbers!
Symmetric Encryption 101
 I Know: Let's Add A Different Number!


01 04 01 54 95 42 64 12

+10 43 21 95 42 67 31 83

11 47 22 49 37 09 95 95
How It Works
We can generate the pads in two ways
● Randomly
  ○ If we only use once, perfect security
    ■ Known as a one-time-pad
  ○ If we use multiple times, same as caesar
    cipher
● With A Function
  ○ Give one or two inputs
    ■ A key, and an "input"
  ○ Generates a "stream" of pseudo random
    numbers
Ciphers
● Take 2 inputs
  ○ A secret key
  ○ An "input"


● Produces Pseudo-Random Output
  ○ Looks random (statistically)
  ○ Is deterministic
     ■ Reproducible given same inputs
Modes
● Multiple ways to use the keystream


● Each way is known as a "Mode"


● Some are secure
  ○ Others are not
ECB
Electronic Code Book

● Uses plain-text as "input"


● Uses output as cipher-text


●   VERY BROKEN!!!
ECB
CBC
Cipher Block Chaining
● Uses an "Initialization Vector"
  ○   Helps "randomize" the plain-text
  ○   Ensures no non-unique blocks
  ○   Does NOT need to be secret
● Chains each block together
  ○ Propagating the generated "randomness"
● Plain-Text Must Be Padded
  ○ To a multiple of block-size
● Secure!
CBC
CFB
Cipher FeedBack
● Uses an "Initialization Vector"

● Plain-Text never enters cipher
  ○ Does not need to be padded


● "Decrypt" Is Never Used

● Secure!
CFB
Ciphers
● AES 128 & 256
  ○ Standard
     ■ NIST Approved
  ○ Also Known As RIJNDAEL-128
     ■ 128 here refers to "block size"
  ○ Very Strong
  ○ Note, the number after AES is *key size*
● Blowfish
● TwoFish
● Serpent
Authentication
How do you know it wasn't tampered
with / came from your friend?
● HMAC
  ○   Hash-based Message Authentication Code
● USE A SEPARATE KEY!
● Encrypt-Then-MAC
  ○ Always MAC after encryption
All Together
    Now!
Encrypt
$key = 'xxxxxxxxxxxxxxxx';
$authKey = 'XXXXXXXXXXXXXX';
$plain = 'This is plain text that I am going to encrypt';


$size = mcrypt_get_iv_size(
     MCRYPT_RIJNDAEL_128,
     MCRYPT_MODE_CFB
);


$iv = mcrypt_create_iv(
     $size,
     MCRYPT_DEV_URANDOM
);
$cipherText = mcrypt_encrypt(
    MCRYPT_RIJNDAEL_128,
     $key,
     $plain,
     MCRYPT_MODE_CFB,
     $iv
);
$auth = hash_hmac('sha512', $cipherText, $authKey, true);
$encrypted = base64_encode($iv . $cipherText . $auth);
Decrypt
$key = 'xxxxxxxxxxxxxxxx';
$authKey = 'XXXXXXXXXXXXXX';


$size = mcrypt_get_iv_size(
     MCRYPT_RIJNDAEL_128,
     MCRYPT_MODE_CFB
);
$encrypted = base64_decode($encrypted);
$iv = substr($encrypted, 0, $size);
$auth = substr($encrypted, -64);
$cipherText = substr($encrypted, $size, -64);
if ($auth != hash_hmac('sha512', $cipherText, $authKey, true)) {
     // Auth Failed!!!
     return false;
}
$plainText = mcrypt_decrypt(
    MCRYPT_RIJNDAEL_128,
     $key,
     $cipherText,
     MCRYPT_MODE_CFB,
     $iv
);
Please Don't Do It!
● Notice How Much Code It Took
  ○ Without error checking
● Notice How Complex It Is
  ○ Without flexibility
● Notice How Easy To Screw Up
  ○ Without Key Storage
● Notice How Many Decisions To Make
If you MUST,
Use a Library
Common Encryption Needs
●   Between Client / Server
    ○ Use SSL
    ○ Really, just use SSL
    ○ I'm not kidding, just use SSL
●   Storage
    ○ Use disk encryption
    ○ Use database encryption
Really,
Don't Do It!
Encryption Resources
● Zend Framework Encryption
  ○ Very good and complete lib
  ○ ZF2
    ■ ZendCryptBlockCipher
● PHP Sec Lib
  ○ phpseclib.sourceforge.net
  ○ Pure PHP
● Not Many Others
  ○ Beware of online tutorials!!!
Password
 Storage
Passwords
  Should Be
 HASHED!
Not Encrypted!
Password Hashes
● Use A Salt
  ○ Defeats Rainbow Tables
  ○ Makes Each Hash a "Proof Of Work"
  ○ Should be random!
    ■ Strong Randomness
● Should Be SLOW!
  ○ Salt is not enough
  ○ Salted SHA256: 11 BILLION per second
  ○ bcrypt: 3200 per second
Good Algorithms

crypt($password, $salt);
pbkdf2($password, $salt, $i);
password_hash(
    $password,
    PASSWORD_BCRYPT
);
$passLib->hash($password);
$phpass->hashPassword($pass);
Cost Parameter
● Target: 0.25 - 0.5 Seconds
  ○ As slow as you can afford

● Depends on hardware
  ○ Test it!

● Good Defaults:
  ○ BCrypt: 10
  ○ PBKDF2: 10,000
Simplified
Password
 Hashing
New API for 5.5
●   string password_hash($pass,         $algo, array $options =
    array() )

    ○   Generates Salt, hashes password
●   bool password_verify($pass, $hash)
    ○   Verifies Hash with Password
●   bool password_needs_rehash($hash,   $algo, array $options = array())

    ○   Determines if the hash is the same as
        specified by algo and options
●   array password_get_info($hash)
     ○ Returns information about the hash
Example
function register($user, $password) {
    $hash = password_hash($password, PASSWORD_BCRYPT);
    $this->store($user, $hash);
}

function login($user, $password) {
    $hash = $this->fetchHash($user);
    if (password_verify($password, $hash)) {
        if (password_needs_rehahs($hash, PASSWORD_BCRYPT)) {
            $hash = password_hash($password, PASSWORD_BCRYPT);
            $this->store($user, $hash);
        }
        $this->startSession();
        return true;
    }
    return false;
}
Hashing Resources
● PHP 5.5 API
  ○ wiki.php.net/rfc/password_hash
● Password Compat
  ○ PHP 5.5 Compatibility
  ○ github/ircmaxell/password_compat
● PasswordLib
  ○ 5.3+, Multiple Algorithms, Portable
  ○ github/ircmaxell/PHP-PasswordLib
● PHPASS
  ○ PHP 4+
  ○ openwall.com/phpass
Seriously,
Hire an Expert!
You Have Been
  Warned
Questions?

 Comments?

Snide Remarks?
Anthony Ferrara
    @ircmaxell
blog.ircmaxell.com
me@ircmaxell.com
   joind.in/7939

Cryptography For The Average Developer

  • 1.
    Cryptography In PHP For The Average Developer
  • 2.
    Cryptography ● Keeping DataSecure ○ Safe From Viewing ○ Safe From Tampering ○ Safe From Forgery ● Not A Silver Bullet ○ XSS ○ SQLI ○ Social Engineering ● Very Hard To Do ○ Any bug will cause problems
  • 3.
    The First Rule ofCryptography
  • 4.
  • 5.
    Leave It For Experts
  • 6.
    Random! The Foundation ofCryptography ● Classified Under Three Types: ○ Weak ■ For non-cryptographic usages ○ Strong ■ For cryptographic usages where security does not depend on the strength of randomness ○ Cryptographically Secure ■ For cryptographic usage when security does depend on the strength of randomness
  • 7.
    Vulnerabilities of Randomness ● Bias ○ Certain values tend to occur more often making it easier to predict future numbers ● Predictability ○ Knowing past numbers helps predict future numbers ● Poisoning ○ Ability to alter future random number generation
  • 8.
    Weak Random inPHP Not to be used for cryptographic usages!!! ● rand() ● mt_rand() ● uniqid() ● lcg_value()
  • 9.
    Strong Random inPHP ● mcrypt_create_iv() ○ MCRYPT_DEV_URANDOM ● openssl_random_pseudo_bytes() ● /dev/urandom ○ For *nix systems only
  • 10.
    Cryptographically Secure ● mcrypt_create_iv() ○ MCRYPT_DEV_RANDOM ● openssl_random_pseudo_bytes() ○ Maybe ● /dev/random ○ For *nix systems only
  • 11.
  • 12.
  • 13.
    If In Doubt Use Strong Randomness
  • 14.
    Encryption vs Hashing ●Encryption ○ Encoding ○ 2 Way / Reversible ○ Putting a lock on a box ● Hashing ○ Signing ○ 1 Way / Non-Reversible ○ Taking a person's finger-print
  • 15.
  • 16.
  • 17.
    Terms ● Key ○ Secure string of data ● Plain-Text ○ The text you want to keep secret ● Cipher-Text ○ The encrypted output
  • 18.
    Two Basic Types ●Symmetric Encryption ○ Like a Pad-Lock with a shared key ○ The only secret is the key ○ Both sides must have the same key ● Asymmetric Encryption ○ Like a pair of Pad-Locks ■ The "lock" is the public key ○ The only secret is the private key ○ Both sides have their own key
  • 19.
    Symmetric Encryption 101 ●Number: 01 Scratch That ● Numbers: 01 04 01 54 95 42 64 12
  • 20.
    Symmetric Encryption 101 Let's Add A "Secret" Number! 01 04 01 54 95 42 64 12 +10 11 14 11 64 05 52 74 22
  • 21.
    Secret Numbers ● Wejust invented the Caesar Cipher ○ Commonly known as "ROT13" ● But There Are Problems: ○ Vulnerable To Statistical Attacks ○ Vulnerable To Brute Forcing ■ Only 100 possible secret numbers!
  • 22.
    Symmetric Encryption 101 I Know: Let's Add A Different Number! 01 04 01 54 95 42 64 12 +10 43 21 95 42 67 31 83 11 47 22 49 37 09 95 95
  • 23.
    How It Works Wecan generate the pads in two ways ● Randomly ○ If we only use once, perfect security ■ Known as a one-time-pad ○ If we use multiple times, same as caesar cipher ● With A Function ○ Give one or two inputs ■ A key, and an "input" ○ Generates a "stream" of pseudo random numbers
  • 24.
    Ciphers ● Take 2inputs ○ A secret key ○ An "input" ● Produces Pseudo-Random Output ○ Looks random (statistically) ○ Is deterministic ■ Reproducible given same inputs
  • 25.
    Modes ● Multiple waysto use the keystream ● Each way is known as a "Mode" ● Some are secure ○ Others are not
  • 26.
    ECB Electronic Code Book ●Uses plain-text as "input" ● Uses output as cipher-text ● VERY BROKEN!!!
  • 27.
  • 28.
    CBC Cipher Block Chaining ●Uses an "Initialization Vector" ○ Helps "randomize" the plain-text ○ Ensures no non-unique blocks ○ Does NOT need to be secret ● Chains each block together ○ Propagating the generated "randomness" ● Plain-Text Must Be Padded ○ To a multiple of block-size ● Secure!
  • 29.
  • 30.
    CFB Cipher FeedBack ● Usesan "Initialization Vector" ● Plain-Text never enters cipher ○ Does not need to be padded ● "Decrypt" Is Never Used ● Secure!
  • 31.
  • 32.
    Ciphers ● AES 128& 256 ○ Standard ■ NIST Approved ○ Also Known As RIJNDAEL-128 ■ 128 here refers to "block size" ○ Very Strong ○ Note, the number after AES is *key size* ● Blowfish ● TwoFish ● Serpent
  • 33.
    Authentication How do youknow it wasn't tampered with / came from your friend? ● HMAC ○ Hash-based Message Authentication Code ● USE A SEPARATE KEY! ● Encrypt-Then-MAC ○ Always MAC after encryption
  • 34.
  • 35.
    Encrypt $key = 'xxxxxxxxxxxxxxxx'; $authKey= 'XXXXXXXXXXXXXX'; $plain = 'This is plain text that I am going to encrypt'; $size = mcrypt_get_iv_size( MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CFB ); $iv = mcrypt_create_iv( $size, MCRYPT_DEV_URANDOM ); $cipherText = mcrypt_encrypt( MCRYPT_RIJNDAEL_128, $key, $plain, MCRYPT_MODE_CFB, $iv ); $auth = hash_hmac('sha512', $cipherText, $authKey, true); $encrypted = base64_encode($iv . $cipherText . $auth);
  • 36.
    Decrypt $key = 'xxxxxxxxxxxxxxxx'; $authKey= 'XXXXXXXXXXXXXX'; $size = mcrypt_get_iv_size( MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CFB ); $encrypted = base64_decode($encrypted); $iv = substr($encrypted, 0, $size); $auth = substr($encrypted, -64); $cipherText = substr($encrypted, $size, -64); if ($auth != hash_hmac('sha512', $cipherText, $authKey, true)) { // Auth Failed!!! return false; } $plainText = mcrypt_decrypt( MCRYPT_RIJNDAEL_128, $key, $cipherText, MCRYPT_MODE_CFB, $iv );
  • 37.
    Please Don't DoIt! ● Notice How Much Code It Took ○ Without error checking ● Notice How Complex It Is ○ Without flexibility ● Notice How Easy To Screw Up ○ Without Key Storage ● Notice How Many Decisions To Make
  • 38.
  • 39.
    Common Encryption Needs ● Between Client / Server ○ Use SSL ○ Really, just use SSL ○ I'm not kidding, just use SSL ● Storage ○ Use disk encryption ○ Use database encryption
  • 40.
  • 41.
    Encryption Resources ● ZendFramework Encryption ○ Very good and complete lib ○ ZF2 ■ ZendCryptBlockCipher ● PHP Sec Lib ○ phpseclib.sourceforge.net ○ Pure PHP ● Not Many Others ○ Beware of online tutorials!!!
  • 42.
  • 43.
    Passwords ShouldBe HASHED! Not Encrypted!
  • 44.
    Password Hashes ● UseA Salt ○ Defeats Rainbow Tables ○ Makes Each Hash a "Proof Of Work" ○ Should be random! ■ Strong Randomness ● Should Be SLOW! ○ Salt is not enough ○ Salted SHA256: 11 BILLION per second ○ bcrypt: 3200 per second
  • 45.
    Good Algorithms crypt($password, $salt); pbkdf2($password,$salt, $i); password_hash( $password, PASSWORD_BCRYPT ); $passLib->hash($password); $phpass->hashPassword($pass);
  • 46.
    Cost Parameter ● Target:0.25 - 0.5 Seconds ○ As slow as you can afford ● Depends on hardware ○ Test it! ● Good Defaults: ○ BCrypt: 10 ○ PBKDF2: 10,000
  • 47.
  • 48.
    New API for5.5 ● string password_hash($pass, $algo, array $options = array() ) ○ Generates Salt, hashes password ● bool password_verify($pass, $hash) ○ Verifies Hash with Password ● bool password_needs_rehash($hash, $algo, array $options = array()) ○ Determines if the hash is the same as specified by algo and options ● array password_get_info($hash) ○ Returns information about the hash
  • 49.
    Example function register($user, $password){ $hash = password_hash($password, PASSWORD_BCRYPT); $this->store($user, $hash); } function login($user, $password) { $hash = $this->fetchHash($user); if (password_verify($password, $hash)) { if (password_needs_rehahs($hash, PASSWORD_BCRYPT)) { $hash = password_hash($password, PASSWORD_BCRYPT); $this->store($user, $hash); } $this->startSession(); return true; } return false; }
  • 50.
    Hashing Resources ● PHP5.5 API ○ wiki.php.net/rfc/password_hash ● Password Compat ○ PHP 5.5 Compatibility ○ github/ircmaxell/password_compat ● PasswordLib ○ 5.3+, Multiple Algorithms, Portable ○ github/ircmaxell/PHP-PasswordLib ● PHPASS ○ PHP 4+ ○ openwall.com/phpass
  • 51.
  • 52.
  • 53.
  • 54.
    Anthony Ferrara @ircmaxell blog.ircmaxell.com me@ircmaxell.com joind.in/7939