Two Factor Authentication Using PHP

Steven Roddis



What and Why

Consider this:

Example of Hardware Tokens

Smart Cards

OTP Solution

MYPW.com uses VASCO's Digipass

10 minutes so far here

SwEKey

SwEKey: Using Linked OTPs

YubiKey

Isn't the YubiKey great?

More on the YubiKey

The Code (Use CRTL - to zoom out)

<?php
function decode_yubistring($ystring,$secret_aes_key)
{
    
$aes=new AES128();
    
$key=$aes->makeKey(pack('H*',$secret_aes_key));

    
$ydec=array();
    if (
strlen($ystring)>=32)
    {
       
$ydec['token']               =    substr($ystring,-32);
       
$ydec['publicID']            =    substr($ystring,0,strlen($ystring)-32);
       
$ydec['token_bin']           =    modhex_decode($ydec['token']);
       
$ydec['token_hex']           =    bin2hex($ydec['token_bin']);
       
$ydec['token_decoded_bin']   =    $aes->blockDecrypt($ydec['token_bin'], $key);
       
$ydec['token_decoded_hex']   =    bin2hex($ydec['token_decoded_bin']);
       
$ydec['secretID_bin']        =    substr($ydec['token_decoded_bin'],0,6);
       
$ydec['secretID_hex']        =    bin2hex($ydec['secretID_bin']);
       
$ydec['counter']             =    ord($ydec['token_decoded_bin'][7])*256+ord($ydec['token_decoded_bin'][6]);
       
$ydec['counter_session']     =    ord($ydec['token_decoded_bin'][11]);
       
$ydec['timestamp']           =    ord($ydec['token_decoded_bin'][10])*65536+ord($ydec['token_decoded_bin'][9])*256+ord($ydec['token_decoded_bin'][8]);
       
$ydec['random']              =    ord($ydec['token_decoded_bin'][13])*256+ord($ydec['token_decoded_bin'][12]);
       
$ydec['crc']                 =    ord($ydec['token_decoded_bin'][15])*256+ord($ydec['token_decoded_bin'][14]);
       
$ydec['crc_ok']              =    crc_check($ydec['token_decoded_bin']);
    }
    return 
$ydec;
}
?>

That it? YubiKey?

  • Implementation is key to proper security (eg. replay attacks)
<?php
if($token['crc_ok'] === true
 
&& strtolower($user['sid']) === strtolower($token['secretID_hex']))
{
    
$counter $token['counter'];
    
$session $token['counter_session'];
    unset(
$token);
     
    
//Do the checks
    
if(($counter $store['counter'])
     OR (
$counter === $store['counter'] && $session $store['session'])) //OK
    
{
?>

A Cheap Low Volume Solution

  • SMS Tokens
  • Send a random code to a mobile.
  • SMSGlobal charges 10c per international SMS
  • Promo code: gloss
  • rand() is weak, mt_rand() is still cryptographically weak
<?php
getpage
('https://www.smsglobal.com.au/http-api.php?action=sendsms&user=USERNAME&password=PASSWORD&from=Steven&to='
.urlencode($row['phone']).'&text='.urlencode($smscode
.' is your SMS Code! Have fun. :)'));
?>

Shameless Plugs

stevenroddis.com
whatsthetide.com






bye