/* pre-compute the key expansion buffer */ memcpy( pke, "Pairwise key expansion", 23 ); if( memcmp( ap->wpa.stmac, ap->bssid, 6 ) < 0 ) { memcpy( pke + 23, ap->wpa.stmac, 6 ); memcpy( pke + 29, ap->bssid, 6 ); } else { memcpy( pke + 23, ap->bssid, 6 ); memcpy( pke + 29, ap->wpa.stmac, 6 ); } if( memcmp( ap->wpa.snonce, ap->wpa.anonce, 32 ) < 0 ) { memcpy( pke + 35, ap->wpa.snonce, 32 ); memcpy( pke + 67, ap->wpa.anonce, 32 ); } else { memcpy( pke + 35, ap->wpa.anonce, 32 ); memcpy( pke + 67, ap->wpa.snonce, 32 ); } // then to get the PTK, they used the string above, like so: /* compute the pairwise transient key and the frame MIC */ for (i = 0; i < 4; i++) { pke[99] = i; HMAC(EVP_sha1(), pmk[j], 32, pke, 100, ptk[j] + i * 20, NULL); /* unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, const unsigned char *d, int n, unsigned char *md, unsigned int *md_len); */ } #### #!/usr/bin/perl -w use strict; use Crypt::PBKDF2; use Digest::HMAC_SHA1 qw(hmac_sha1 hmac_sha1_hex); use List::Util qw( min max ); my $usage = "Usage: perl wpa2hex \n"; my $essid = shift || die $usage; my $passwd = shift || die $usage; # pack the next few registers up my $smac = pack("H*","489d2477179a"); # station MAC (RIM) my $amac = pack("H*","001dd0f694b0"); # AP MAC (Arris) my $snonce = pack("H*","143fbb4333341f36e17667f88aa02c5230ab82c508cc4bd5947dd7e50475ad36"); my $anonce = pack("H*","87f2718bad169e4987c94255395e054bcaf77c8d791698bf03dc85ed3c90832a"); my $pbkdf2 = Crypt::PBKDF2->new( hash_class => 'HMACSHA1', # HMAC-SHA1 hash_args => { sha_size => 512, },iterations => 4096, salt_len => length($essid), output_len => 32 ); my $pmk = uc($pbkdf2->PBKDF2($essid, $passwd)); my $pbkdf2b = Crypt::PBKDF2->new( hash_class => 'HMACSHA1', # HMAC-SHA1 hash_args => { sha_size => 512, },iterations => 4096, salt_len => length($pmk), output_len => 20 ); print "Master Key: ",uc(unpack("H*",$pmk)),"\n"; prf512(); sub prf512{ my $a = "Pairwise key expansion"; # application-specific data my $b = $amac.$smac.$snonce.$anonce; my $r = ""; for(my $i=0;$i<4;$i++){ my $data = $a."\x00".$b.$i; $r .= $pbkdf2b->PBKDF2($pmk,$data); } print "Transient Key: ",uc(unpack("H*",$r)),"\n"; return; }