DES With Perl
发布时间:2020-12-16 00:32:09 所属栏目:大数据 来源:网络整理
导读:原本是要放在 NTLM Protocol - 2. DES 编码 这篇文章中,但不知是不是该章内容太大还是啥么原因,怎么也传不上,就拉出来单独放着. #!/usr/bin/perl -w# DES algorithm - reference to http://orlingrabbe.com/des.htmsub iteration_handle { my ($bitstring,$p
原本是要放在 NTLM Protocol - 2. DES 编码 这篇文章中,但不知是不是该章内容太大还是啥么原因,怎么也传不上,就拉出来单独放着. #!/usr/bin/perl -w # DES algorithm - reference to http://orlingrabbe.com/des.htm sub iteration_handle { my ($bitstring,$pad) = @_; my $bitstringp = pack 'b*',$bitstring; my @bitarray = split(//,unpack('b*',$bitstringp)); my @subkey; # perl give four zeros append the last of packed string my ($d1,$d2) = (scalar(@bitarray) - 4,scalar(@bitarray) - 1); delete @bitarray[$d1..$d2]; #print "PAD=$padn"; # handle last $pad bits for ($n=$pad; $n>0; $n--) { $subkey[scalar(@bitarray)-$n] = $bitarray[$pad - $n]; } # handle head of bits for($i=0; $i<(scalar(@bitarray)-$pad); $i++) { #if ($i == $#bitarray) { # $subkey[$i] = $bitarray[0]; #} else { $subkey[$i] = $bitarray[$i+$pad]; #} #print $i. ": ". $subkey[$i]. "n"; } return join('',@subkey); } sub tobit { my $uncode = shift; my %codemap = ('0' => '0000','1' => '0001','2' => '0010','3' => '0011','4' => '0100','5' => '0101','6' => '0110','7' => '0111','8' => '1000','9' => '1001','A' => '1010','B' => '1011','C' => '1100','D' => '1101','E' => '1110','F' => '1111'); my $coded = ''; my @chars = split('',$uncode); foreach $c (@chars) { $coded .= $codemap{$c}; } return $coded; } sub tohex { my $origin = shift; my @hexbits = split(//,$origin); my $ret = ''; for ($j=0; $j<@hexbits; $j=$j+4) { $hex = join '',@hexbits[$j..($j+3)]; $ret .= sprintf ("%x",oct('0b' .$hex)); } return $ret; } sub permuted { my $unpermuted = shift; # the first permutation chooser map table my @pc1map = (57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,27,19,11,3,60,52,44,36,63,55,47,39,31,23,15,7,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,28,20,12,4); my $permuted = ''; my @unpermutation = split(//,$unpermuted); foreach $d (@pc1map) { $permuted .= $unpermutation[$d-1]; # start from index 1 } return $permuted; } sub generate_subkey { my $origin = shift; # the second permutation chooser map table my @pc2map = (14,24,4,8,16,40,48,56,32); my $permuted = ''; my @unpermutation = split(//,$origin); foreach $d (@pc2map) { $permuted .= $unpermutation[$d-1]; # start from index 1 } return $permuted; } sub initial_permutation { my $origin = shift; # the initial permutation map table my @IP = (58,64,32,57,7); my $permuted = ''; my @unpermutation = split(//,$origin); foreach $d (@IP) { $permuted .= $unpermutation[$d-1]; # start from index 1 } return $permuted; } sub expand { my $origin = shift; # bit selection table my @selection_table = (32,1); my $permuted = ''; my @unpermutation = split(//,$origin); foreach $d (@selection_table) { #print "array of position $d: $unpermutation[$d-1]n"; $permuted .= $unpermutation[$d-1]; # start from index 1 } return $permuted; } sub subxor { my ($a,$b) = @_; my @as = split(//,$a); my @bs = split(//,$b); my @targets; for ($z=0; $z<@as; $z++) { if ($as[$z] eq '0' && $bs[$z] eq '0') { $targets[$z] = '0'; } elsif ($as[$z] eq '1' && $bs[$z] eq '1') { $targets[$z] = '0'; } else { $targets[$z] = '1'; } } return join '',@targets; } sub cal_sboxes { my $origin = shift; my @sboxes; my @scalars = split(//,$origin); my @sb1 = (14,13); my @sb2 = (15,9); my @sb3 = (10,12); my @sb4 = ( 7,14); my @sb5 = ( 2,3); my @sb6 = (12,13); my @sb7 = ( 4,12); my @sb8 = (13,11); @sboxes = (@sb1,@sb2,@sb3,@sb4,@sb5,@sb6,@sb7,@sb8); my $ret = ''; my $index = 0; for ($i=0; $i<@scalars; $i=$i+6,$index++) { $row = oct('0b'. join ('',@scalars[$i,($i+5)])); $col = oct ('0b'. join ('',@scalars[($i+1)..($i+4)])); #print "ROW: $row,COL= $coln"; $sindex = $row == 0 ? ($row * 15 + $col) : ($row * 16 + $col); #print "SINDEX = $sindexn"; #print "ROW= $row,COL= $col,V= $sboxes[$index][$sindex]n"; #print sprintf("%04b",$sboxes[$index][$sindex]); $ret .= sprintf("%04b",$sboxes[$index][$sindex]); } return $ret; } sub second_permutation { my $origin = shift; # bit selection table my @sp = (16,25); my $permuted = ''; my @unpermutation = split(//,$origin); foreach $d (@sp) { $permuted .= $unpermutation[$d-1]; # start from index 1 } return $permuted; } sub handle_func { my ($rp,$key) = @_; # expand $rp[n-1] from 32 bits to 48 bits my $expands = expand $rp; #print "EXP= $expandsn"; # XOR my $xor = subxor $key,$expands; #print "XOR= $xorn"; my $ret = ''; # calcute sboxes my $sbs = cal_sboxes($xor); #print "SBS= $sbsn"; $ret = second_permutation $sbs; #print "FP = $retn"; return $ret; } sub final_permutation { my $origin = shift; # bit selection table my @fp = (40,$origin); foreach $d (@fp) { $permuted .= $unpermutation[$d-1]; # start from index 1 } return $permuted; } # Step1: Create 16 subkeys,each of which is 48-bits long. $original_key = '133457799BBCDFF1'; #print "KEY = ". $original_key. "n"; my $keybits = tobit $original_key; #print "K = ". $keybits. "n"; $permutation = permuted $keybits; #print "K+ = ". $permutation. "nn"; my @subkeys; $subkeys[0] = $permutation; my @permutations = split(//,$permutation); my @leftpart; my @rightpart; $leftpart[0] = join('',@permutations[0..27]); $rightpart[0] = join ('',@permutations[28..55]); #print "C0: ". $leftpart[0]. "n"; #print "D0: ". $rightpart[0]. "nn"; # irations table for shift N my %iterations = (1 => 1,2 => 1,3 => 2,4 => 2,5 => 2,6 => 2,7 => 2,8 => 2,9 => 1,10 => 2,11 => 2,12 => 2,13 => 2,14 => 2,15 => 2,16 => 1); for ($j=1; $j<=16; $j++) { $leftpart [$j] = iteration_handle $leftpart[$j-1],$iterations{$j}; $rightpart[$j] = iteration_handle $rightpart[$j-1],$iterations{$j}; #print "C". $j. " = ". $leftpart[$j]. "n"; #print "D". $j. " = ". $rightpart[$j]. "nn"; $subkeys[$j] = generate_subkey($leftpart[$j]. $rightpart[$j]); #print "K". $j. " = ". $subkeys[$j]. "n"; } # Step 2: Encode each 64-bit block of data my $data = '0123456789ABCDEF'; print "DATA = ". $data. "n"; my $ip = initial_permutation(tobit($data)); #print "IP = ". $ip. "n"; # $ip = $lp[0] + $rp[0] my (@lp,@rp); $lp[0] = join '',(split(//,$ip))[0..31]; $rp[0] = join '',$ip))[32..63]; #print "L0 = ". $lp[0]. "n"; #print "R0 = ". $rp[0]. "n"; for ($x=1; $x<=16; $x++) { $lp[$x] = $rp[$x-1]; #print "L". $x. " = ". $lp[$x]. "n"; #print "R". ($x-1). " = ". $rp[$x-1]. "n"; #print "K". $x. " = ". $subkeys[$x]. "n"; #print "L". ($x-1). " = ". $lp[$x-1]. "n"; $rp[$x] = subxor($lp[$x-1],handle_func($rp[$x-1],$subkeys[$x])); #print "R". $x. " = ". $rp[$x]. "n"; } my $reverse = $rp[16]. $lp[16]; #print "R16L16 = ". $reverse. "n"; my $final = final_permutation $reverse; $final = uc(tohex $final); print "FINAL = $finaln"; 其执行结果如下: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |