Differences

This shows you the differences between two versions of the page.

Link to this comparison view

john:pp_PBKDF2 [2014/09/04 19:26] (current)
JimF created
Line 1: Line 1:
 +Here is a very simple Perl script that does PBKDF2-HMAC-* functions. ​ These functions (hmac_pad, pp_pbkdf2 and pp_pbkdf2_hex) have been incorporated into the pass_gen.pl script in JtR main runtime (bleeding edge). ​ I simply put these functions here to publish them for anyone to be able to find, and to be indexed into search engines. ​ This code is pretty flexible, allowing the '​flawed'​ (IMHO) HMAC function with about any crypto algorithm to be used in the PBKDF2 key stretching function.
 +
 +Written by Jim Fougeron, Sept, 2014 and hereby placed in public domain.
 +
 +<code perl>
 +#​!/​usr/​bin/​perl -w
 +
 +# pp_pbkdf2.pl ​ this is a SUPER simple pure Perl pbkdf2-hmac-*crypt implementation.
 +#
 +# Copyright (C) Sept 2014, Jim Fougeron.
 +# This code is hereby released into public domain as long as this Copyright statement is maintained.
 +# This software may be modified, redistributed,​ and used for any purpose, in source and binary forms,
 +# with or without modification,​ as long as this copyright statement is maintained.
 +
 +# test vectors.
 +# ./​pp_pbkdf2.pl password CKrgSLbQECwE 10000 sha256 32  output: 41dbfab2f658346b325c7a7f29ef1735e1c07d40370157a58ddbfa9ec5108dd4
 +# ./​pp_pbkdf2.pl password kIIWWNB 24000 sha512 68       ​output:​ 50d71996d584cce98ea14ffeaf12adc447173b8c333b5c6191ab97a101d2c3b56216ed892e28fcc78d84f39a0d33b1eb5ae2e36cb46ec30211366f0af270f6b405ff26c8
 +# ./​pp_pbkdf2.pl password BadAlgo 4800 md5 40           ​output:​ df6495d5493ff96802a6b557c814d32a3f8917687d9dcd2be6b6b3bcaa2d09f6cb8e81b413c96454
 +#
 +# algo can be any of these: ​  md4 md5 sha1 sha224 sha256 sha384 sha512 tiger haval256. ​ Others could easily be used.
 +# the only '​issue'​ is in computing the width of the HMAC data.
 +#
 +# NOTE, this code does not perform the optimization of doing the first limb hash of ipad and opad, and re-using those results.
 +# I have not found an optimal way to do that in perl, like I have done in the JtR code base.
 +#
 +use POSIX;
 +use strict;
 +use Digest::SHA qw(sha256 sha1 sha224 sha384 sha512);
 +use Digest::MD5 qw(md5);
 +use Digest::MD4 qw(md4);
 +
 +sub tiger {
 + require Digest::​Tiger;​
 + return Digest::​Tiger::​hash($_[0]);​
 +}
 +sub haval256 {
 + require Digest::​Haval256;​
 + my $hash = new Digest::​Haval256;​
 + $hash->​add($_[0]);​
 + return $hash->​digest;​
 +}
 +
 +sub hmac_pad {
 + my ($pass, $ch, $algo) = @_;
 + my $pad;  # ipad or opad, depending upon ch passed in.
 + no strict '​refs';​
 + $pad = &​$algo("​a"​);​
 + use strict;
 + my $len = (length($pad)>​= 48) ? 128 : 64; # I am not 100% sure this is valid for ALL algos.
 + $pad = $ch x $len;
 + if (length($pass) > $len) { no strict '​refs';​ $pass = &​$algo($pass);​ use strict; }
 + $pad ^= $pass;
 + return $pad;
 +}
 +sub pp_pbkdf2 {
 + my ($pass, $orig_salt, $iter, $algo, $bytes) = @_;
 + my $ipad = hmac_pad($pass,​ '​6',​ $algo); ​ # 6 is \x36 for an ipad
 + my $opad = hmac_pad($pass,​ '​\\',​ $algo); # \ is \x5c for an opad
 + my $final_out="";​ my $i=1;
 + while (length($final_out) < $bytes) {
 + my $salt = $orig_salt . chr($i>>​24);​ $salt .= chr(($i>>​16)&​0xFF);​ $salt .= chr(($i>>​8)&​0xFF);​ $salt .= chr($i&​0xFF);​
 + $i += 1;
 + no strict '​refs';​
 + $salt = &​$algo($opad.&​$algo($ipad.$salt));​
 + use strict;
 + my $out = $salt;
 + for (my $i = 1; $i < $iter; $i += 1) {
 + no strict '​refs';​
 + $salt = &​$algo($opad.&​$algo($ipad.$salt));​
 + use strict;
 + $out ^= $salt;
 + }
 + if (length($final_out)+length($out) > $bytes) {
 + $out = substr($out,​ 0, $bytes-length($final_out));​
 + }
 + $final_out .= $out;
 + }
 + return $final_out;
 +}
 +sub pp_pbkdf2_hex {
 + my ($pass, $salt, $iter, $algo, $bytes) = @_;
 + return unpack("​H*",​ pp_pbkdf2($pass,​$salt,​$iter,​$algo,​$bytes));​
 +}
 +
 +if (!defined($ARGV[4])) { print "Usage pp_pbkdf2.pl pass salt count algo bytes_wanted\n";​ exit (1); }
 +print pp_pbkdf2_hex($ARGV[0],​$ARGV[1],​$ARGV[2],​$ARGV[3],​$ARGV[4]) . "​\n";​
 +</​code>​
  
john/pp_PBKDF2.txt ยท Last modified: 2014/09/04 19:26 by JimF
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate to DokuWiki Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki Powered by OpenVZ Powered by Openwall GNU/*/Linux