Yubico Forum

...visit our web-store at store.yubico.com
It is currently Tue Jan 30, 2018 3:08 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 12 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Mon May 26, 2008 9:56 pm 
Offline

Joined: Sun May 25, 2008 5:06 pm
Posts: 27
Hi,

Here is my first implementation of a function for PHP that decrypts an OPT-string from a yubikey. It works completely independent of yubico's servers. The only thing you need to change in the code is the AES-key of your yubikey. This code does not check for OTP-replays! it's your job to check the counter and the sessioncounter!

Just put the code on your webserver together with the AES128-class you can download from here: http://www.phpclasses.org/browse/file/17721.html

way of calling:
decode_yubistring($ystring,$secret_aes_key)

ystring: String from the yubikey
secret_aes_key: your 128 bit AES-key presented in HEX

returns array:
publicID: The first part of the OPT-string. Normally the id of your yubikey

token: The last 32 yubikey characters of the OPT-string. This is going to be decrypted
token_bin: Token presented binary.
token_hex: Token presented in hex.

aeskey_bin: Your secret AES-key in binary format
aeskey_hex: Your secret AES-key in hex

token_decoded_bin: Decoded token in binary format
token_decoded_hex: Decoded token in hex

secretID_bin: Decrypted secret ID
secretID_hex: Decrypted secret ID in hex
counter: Decrypted number of times the yubikey has been powered up
counter_session: Decrypted number of times the yubikey has been pressed since last power up
timestamp: Decrypted number of 1/8sek since power up
random: Decrypted random number generated by the yubikey
crc: Decrypted CRC checksom generated by the yubikey

crc_ok=True if the checksum of the decrypted data is ok. Always check this!

Here comes my sourcecode:

Code:
<html>
   <head></head>
   <body>
      <form method="post" action="<?php echo $PHP_SELF; ?>">
         Press your Yubikey:
         <input type="text" name="yubistring" size="50">
         <input type="submit" value="submit">
      </form>

      <?PHP
         /*
            PHP yubikey decryptor v0.1 by Alex Skov Jensen.
            
            This program will ONLY decrypt data from your key. You have to check the crc_ok, counter and counter_session variables in order to very prevent OTP-replays!

            You need to download the AES128 library from: http://www.phpclasses.org/browse/file/17721.html in order to use this program
            Call decode_yubistring($yubistring,$aes_key) function. Function returnes an array with all decrypted information from the yubikey.
         */
         
         // The secret AES key of your yubikey - the only parameter you need to set!
         $secret_aes_key="802dce501d8547d6832a48c5da0c89af";

         $t=decode_yubistring($_POST["yubistring"],$secret_aes_key);
         while (list($key, $value) = each($t)) echo "$key=$value<br />\n";


         function decode_yubistring($ystring,$secret_aes_key)
         {
            require_once('AES128.php');
            $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["aeskey_bin"]=pack('H*',$secret_aes_key);
               $ydec["aeskey_hex"]=$secret_aes_key;
               $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;
         }

         function crc_check($buffer)
         {
            $m_crc=0xffff;
            for($bpos=0; $bpos<16; $bpos++)
            {
               $m_crc ^= ord($buffer[$bpos]) & 0xff;
               for ($i=0; $i<8; $i++)
               {
                  $j=$m_crc & 1;
                  $m_crc >>= 1;
                  if ($j) $m_crc ^= 0x8408;
               }
            }
            return $m_crc==0xf0b8;
         }

         function modhex_decode($mstring)
         {
            $cset="cbdefghijklnrtuv";
            $decoded="";
            $hbyte=0;
            for ($i=0; $i<strlen($mstring);$i++)
            {
               $pos=strpos($cset,$mstring[$i]);
               if ($i/2-round($i/2))
               {
                  $decoded.=chr($hbyte+$pos);
                  $hbyte=0;
               } else $hbyte=$pos*16;
            }
            return $decoded;
         }
      ?>

   </body>
</html>


I hope that you can use it :D Comments are welcome

Best regards,
Alex.


Top
 Profile  
Reply with quote  

Share On:

Share on Facebook FacebookShare on Twitter TwitterShare on Tumblr TumblrShare on Google+ Google+

PostPosted: Wed May 28, 2008 5:47 pm 
Offline
Site Admin
Site Admin

Joined: Tue May 06, 2008 7:22 pm
Posts: 151
Wow, many thanks for sharing this code!

I know that John Woltam has been working on a PHP port as well, and has sent early copies to me. He was going to create a google code project for this tonight, and maybe we can all join that project and maybe pick the best parts from each implementation?

It seems your code may be somewhat shorter... but let's wait with comparison until both are available.

It seems this should be packaged as a PHP class somehow. A PEAR module perhaps? I dunno.

Thanks,
Simon


Top
 Profile  
Reply with quote  
PostPosted: Wed May 28, 2008 9:29 pm 
Offline

Joined: Sun May 25, 2008 5:06 pm
Posts: 27
Here is my readymade class complete with check for OTP replays!!!! You first need to set up a table on a mysql-server in order to store the secret AES keys and the session counters. You do that by using the included SQL-script first. The yubikey_test.php is a running example using the class. It provides almost all usefull information about the yubikey.

http://zyz.dk/yk/class_0.2/sql.html
http://zyz.dk/yk/class_0.2/yubikey.php.html
http://zyz.dk/yk/class_0.2/yubikey_test.php.html

I hope this is better than my first script :)

You still need to download the AES128 class from http://www.phpclasses.org/browse/package/3650.html and place it in the same directory. You can get my copy of that library from: http://zyz.dk/yk/class_0.2/AES128.php.html

Best regards,
Alex


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 05, 2008 5:17 pm 
Offline

Joined: Sun May 25, 2008 5:06 pm
Posts: 27
Here is version 0.3 of my Yubikey PHP class...

Now you can do:
1) simple decryption (with no backend database). You should handle the counters to prevent replay-attacks
2) OTP authentication, preventing replay-attacks using MySQL as backend.
3) OTP authentication, preventing replay-attacks using an INI-file as backend. This makes the setup very simple.

You can find the code and examples here: http://zyz.dk/yk/class_0.3

Best regards,
Alex Jensen


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 06, 2008 10:21 am 
Offline

Joined: Sun May 25, 2008 5:06 pm
Posts: 27
By some help from Mr. John Woltman I restructured the class making it easy to extend the class with your own key-store. You could do that if you don't like MySQL or the provided ini-file option.

Sources, examples and online tests are here: http://zyz.dk/yk/class_0.5/

Best regards,
Alex Jensen


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 09, 2008 8:34 am 
Offline
Site Admin
Site Admin

Joined: Tue May 06, 2008 7:22 pm
Posts: 151
Wow, many thanks for continuing working on this!

We have been busy with production issues, but I think we are close to deciding on how to proceed with an open source based server. I need to take a more careful look at the code, but do you think it would be possible to develop this code in a version control system somewhere? Then people from yubico will put more time into it, and we can even begin advertising it as our open source server and write documentation for it. What do you think?

/Simon


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 09, 2008 12:56 pm 
Offline

Joined: Mon Jun 09, 2008 12:54 pm
Posts: 13
Location: Pennsylvania, U.S.A.
Hello everyone, got my Yubikey and I can now login to the forums! Tonight I plan on trying some new things with my Yubikey, and will post the results either here or in a new thread. Cheers!


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 09, 2008 4:50 pm 
Offline

Joined: Sun May 25, 2008 5:06 pm
Posts: 27
Hi

jwoltman: Congratulations on you new yubikey :) Don't keep pushing the button all night :) And thank you very much for your help about the class abstractions. I am looking forward to seeing a SQlite class from you, if you get the time to make it :)

Simon: It sounds like a good idea - do you have any preferences? I was thinking about sourceforge - I never tried it before, but it looks like that they have good versioning possibilities. Do you have any better suggestions?

Best regards,
Alex


Top
 Profile  
Reply with quote  
PostPosted: Tue Jun 10, 2008 9:38 am 
Offline
Site Admin
Site Admin

Joined: Tue May 06, 2008 7:22 pm
Posts: 151
Alex: It would be great to be able to collaborately improve your work. We have been using Google Code, which supports SVN, successfully. I like their clean interface. I've used sourceforge in the past, but find that it is a bit too complex and contains a lot of advertisement everywhere. But I don't care strongly, and it is your project after all. ;-)

/Simon


Top
 Profile  
Reply with quote  
PostPosted: Tue Jun 10, 2008 6:17 pm 
Offline

Joined: Sun May 25, 2008 5:06 pm
Posts: 27
Hi Simon,

I opened a an account at code.google.com to host the class.
You can find it here: http://code.google.com/p/yubiclass/

I changed the version to 0.6 to keep track of the fact that i moved it from my old site to google.

Best regards,
Alex


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group