DELPHI、PHP、C#通用DES编码解码单元 (DELPHI下使用的代码)

3 篇文章 0 订阅
2 篇文章 0 订阅
unit uDES;
{*********************************************************}
{*          DELPHI、PHP、C#通用DES编码解码单元           *}
{*       blessed  2016-10-18       *}
{*********************************************************}
{EncryStr为编码函数,DecryStr为解码函数,Key为密码,pvIV为偏移量,
一般设置Key,pvIV相同,内容为八位字节长度的字符串,编码结果为十六进制字串}
interface
uses
   Windows, Classes, SysUtils,Dialogs,Base64;
type
   fdArray   = array of dword;
    /// <summary>
    /// DES加密返回BASE64后的数据
    /// </summary>
    /// <param name="Str"></param>
    /// <param name="Key"></param>
    /// <param name="pvIV"></param>
    /// <returns></returns>
   function EncryStr(Str, Key: String;pvIV:string): String;
   /// <summary>
   /// DES解密
   /// </summary>
   /// <param name="Str"></param>
   /// <param name="Key"></param>
   /// <param name="pvIV"></param>
   /// <returns></returns>
   function DecryStr(Str, Key: String;pvIV:string): String;
   /// <summary>
   /// DES加密返回16进制的数据
   /// </summary>
   /// <param name="Str"></param>
   /// <param name="Key"></param>
   /// <param name="pvIV"></param>
   /// <returns></returns>
   function EncryStrHex(Str, Key: String;pvIV:string): String;
   /// <summary>
   /// DES解密
   /// </summary>
   /// <param name="Str"></param>
   /// <param name="Key"></param>
   /// <param name="pvIV"></param>
   /// <returns></returns>
   function DecryStrHex(Str, Key: String;pvIV:string): String;
   function des(key:string;smessage:string;encrypt:dword;mode:dword;iv:string):string;
   function des_createKeys(key:string):fdArray;
   function StrToHex(Str:string):string;
   function HexToStr(Hex:string):string;
   function IsInt(Str:String):Boolean;
implementation
function EncryStr(Str, Key: String;pvIV:string): String;


var i:integer;
  str1:string;
  Astr:string;
  vi:array [0..7] of Byte;
begin
   for i:=0 to 7 do begin
     if i > (length(pvIV)-1) then
      vi[i]:=0
    else
      vi[i] := byte(pvIV[i+1]);
   end;
   for i := 0 to 7 do
    begin
     str1 :=str1 + Chr(vi[i]);
    end;
 Result :=Base64EncodeStr(des(Key, Str, 1, 1, str1));
end;
 
function DecryStr(Str, Key: String;pvIV:string): String;
var i:integer;
   vistr:string;
   vi:array [0..7] of Byte;
begin
   for i:=0 to 7 do begin
     if i > (length(pvIV)-1) then
      vi[i]:=0
    else
      vi[i] := byte(pvIV[i+1]);
   end;
   for i := 0 to 7 do
    begin
     vistr :=vistr + Chr(vi[i]);
    end;
   Result := trim(des(Key, Str, 0, 0, vistr));
end;


function EncryStrHex(Str, Key: String ;pvIV:string): String;


var i:integer;
  vistr:string;
   vi:array [0..7] of Byte;
begin
   for i:=0 to 7 do begin
     if i > (length(pvIV)-1) then
      vi[i]:=0
    else
      vi[i] := byte(pvIV[i+1]);
   end;
   for i := 0 to 7 do
    begin
     vistr :=vistr + Chr(vi[i]);
    end;
   Result := trim(StrToHex(des(Key,Str, 1,1, vistr)));  {1:加密1:CBC }
end;


function DecryStrHex(Str, Key: String;pvIV:string): String;
var i:integer;
   vistr:string;
   vi:array [0..7] of Byte;
begin
   for i:=0 to 7 do begin
     if i > (length(pvIV)-1) then
      vi[i]:=0
    else
      vi[i] := byte(pvIV[i+1]);
   end;
   for i := 0 to 7 do
    begin
     vistr :=vistr + Chr(vi[i]);
    end;
   Result := trim(des(Key, HexToStr(Str), 0, 1, vistr ));
end;


function des(key:string;smessage:string;encrypt:dword;mode:dword;iv:string):string;
const
   spfunction1 : array[0..63] of dword = ($1010400,0,$10000,$1010404,$1010004,$10404,$4,$10000,$400,$1010400,$1010404,$400,$1000404,$1010004,$1000000,$4,$404,$1000400,$1000400,$10400,$10400,$1010000,$1010000,$1000404,$10004,$1000004,$1000004,$10004,0,$404,$10404,$1000000,$10000,$1010404,$4,$1010000,$1010400,$1000000,$1000000,$400,$1010004,$10000,$10400,$1000004,$400,$4,$1000404,$10404,$1010404,$10004,$1010000,$1000404,$1000004,$404,$10404,$1010400,$404,$1000400,$1000400,0,$10004,$10400,0,$1010004);
   spfunction2 : array[0..63] of dword = ($80108020,$80008000,$8000,$108020,$100000,$20,$80100020,$80008020,$80000020,$80108020,$80108000,$80000000,$80008000,$100000,$20,$80100020,$108000,$100020,$80008020,0,$80000000,$8000,$108020,$80100000,$100020,$80000020,0,$108000,$8020,$80108000,$80100000,$8020,0,$108020,$80100020,$100000,$80008020,$80100000,$80108000,$8000,$80100000,$80008000,$20,$80108020,$108020,$20,$8000,$80000000,$8020,$80108000,$100000,$80000020,$100020,$80008020,$80000020,$100020,$108000,0,$80008000,$8020,$80000000,$80100020,$80108020,$108000);
   spfunction3 : array[0..63] of dword = ($208,$8020200,0,$8020008,$8000200,0,$20208,$8000200,$20008,$8000008,$8000008,$20000,$8020208,$20008,$8020000,$208,$8000000,$8,$8020200,$200,$20200,$8020000,$8020008,$20208,$8000208,$20200,$20000,$8000208,$8,$8020208,$200,$8000000,$8020200,$8000000,$20008,$208,$20000,$8020200,$8000200,0,$200,$20008,$8020208,$8000200,$8000008,$200,0,$8020008,$8000208,$20000,$8000000,$8020208,$8,$20208,$20200,$8000008,$8020000,$8000208,$208,$8020000,$20208,$8,$8020008,$20200);
   spfunction4 : array[0..63] of dword = ($802001,$2081,$2081,$80,$802080,$800081,$800001,$2001,0,$802000,$802000,$802081,$81,0,$800080,$800001,$1,$2000,$800000,$802001,$80,$800000,$2001,$2080,$800081,$1,$2080,$800080,$2000,$802080,$802081,$81,$800080,$800001,$802000,$802081,$81,0,0,$802000,$2080,$800080,$800081,$1,$802001,$2081,$2081,$80,$802081,$81,$1,$2000,$800001,$2001,$802080,$800081,$2001,$2080,$800000,$802001,$80,$800000,$2000,$802080);
   spfunction5 : array[0..63] of dword = ($100,$2080100,$2080000,$42000100,$80000,$100,$40000000,$2080000,$40080100,$80000,$2000100,$40080100,$42000100,$42080000,$80100,$40000000,$2000000,$40080000,$40080000,0,$40000100,$42080100,$42080100,$2000100,$42080000,$40000100,0,$42000000,$2080100,$2000000,$42000000,$80100,$80000,$42000100,$100,$2000000,$40000000,$2080000,$42000100,$40080100,$2000100,$40000000,$42080000,$2080100,$40080100,$100,$2000000,$42080000,$42080100,$80100,$42000000,$42080100,$2080000,0,$40080000,$42000000,$80100,$2000100,$40000100,$80000,0,$40080000,$2080100,$40000100);
   spfunction6 : array[0..63] of dword = ($20000010,$20400000,$4000,$20404010,$20400000,$10,$20404010,$400000,$20004000,$404010,$400000,$20000010,$400010,$20004000,$20000000,$4010,0,$400010,$20004010,$4000,$404000,$20004010,$10,$20400010,$20400010,0,$404010,$20404000,$4010,$404000,$20404000,$20000000,$20004000,$10,$20400010,$404000,$20404010,$400000,$4010,$20000010,$400000,$20004000,$20000000,$4010,$20000010,$20404010,$404000,$20400000,$404010,$20404000,0,$20400010,$10,$4000,$20400000,$404010,$4000,$400010,$20004010,0,$20404000,$20000000,$400010,$20004010);
   spfunction7 : array[0..63] of dword = ($200000,$4200002,$4000802,0,$800,$4000802,$200802,$4200800,$4200802,$200000,0,$4000002,$2,$4000000,$4200002,$802,$4000800,$200802,$200002,$4000800,$4000002,$4200000,$4200800,$200002,$4200000,$800,$802,$4200802,$200800,$2,$4000000,$200800,$4000000,$200800,$200000,$4000802,$4000802,$4200002,$4200002,$2,$200002,$4000000,$4000800,$200000,$4200800,$802,$200802,$4200800,$802,$4000002,$4200802,$4200000,$200800,0,$2,$4200802,0,$200802,$4200000,$800,$4000002,$4000800,$800,$200002);
   spfunction8 : array[0..63] of dword = ($10001040,$1000,$40000,$10041040,$10000000,$10001040,$40,$10000000,$40040,$10040000,$10041040,$41000,$10041000,$41040,$1000,$40,$10040000,$10000040,$10001000,$1040,$41000,$40040,$10040040,$10041000,$1040,0,0,$10040040,$10000040,$10001000,$41040,$40000,$41040,$40000,$10041000,$1000,$40,$10040040,$1000,$41040,$10001000,$40,$10000040,$10040000,$10040040,$10000000,$40000,$10001040,0,$10041040,$40040,$10000040,$10040000,$10001000,$10001040,0,$10041040,$41000,$41000,$1040,$1040,$40040,$10000000,$10041000);
var
   keys:fdArray;
   m, i, j,k,mm:integer;
   temp, temp2, right1, right2, left, right:dword;
   looping:array of integer;
   cbcleft, cbcleft2, cbcright, cbcright2:dword;
   endloop, loopinc:integer;
   len, iterations:integer;
   chunk:integer;
   tempresult:string;
begin
   //create the 16 or 48 subkeys we will need
   keys := des_createKeys(key);
   m:=0;cbcleft:=0;cbcleft2:=0;cbcright:=0;cbcright2:=0;chunk:=0;
   len := length(smessage);
   //set up the loops for single and triple des
   if length(keys) = 32 then
     iterations := 3
   else
     iterations := 9;
   if iterations = 3 then
     begin
       if encrypt = 1 then
         begin
           setlength(looping,3);
           looping[0] := 0;
           looping[1] := 32;
           looping[2] := 2;
         end
       else
         begin
           setlength(looping,3);
           looping[0] := 30;
           looping[1] := -2;
           looping[2] := -2;
         end;
     end
   else
     begin
       if encrypt = 1 then
         begin
           setlength(looping,9);
           looping[0] := 0;
           looping[1] := 32;
           looping[2] := 2;
           looping[3] := 62;
           looping[4] := 30;
           looping[5] := -2;
           looping[6] := 64;
           looping[7] := 96;
           looping[8] := 2;
         end
       else
         begin
           setlength(looping,9);
           looping[0] := 94;
           looping[1] := 62;
           looping[2] := -2;
           looping[3] := 32;
           looping[4] := 64;
           looping[5] := 2;
           looping[6] := 30;
           looping[7] := -2;
           looping[8] := -2;
         end;
     end;
   //*********下面的是关键部分及对于c#补位( 待加密数据按照PKCS5规则进行补位。(缺7位补7个0x07,缺6位则补6个0x06,以次类推,如果正好8位,也需要补8个0x08)*********
   mm:=   8-Length(smessage) mod 8 ;
   for k:=0 to mm-1 do
    begin
    smessage:= smessage +chr(mm);
   end;
   //store the result here
   result := '';
   tempresult := '';
   if mode = 1 then //CBC mode (这里也是关键C#DES加密默认是CBC模式)
     begin
       cbcleft := (ord(iv[m+1]) shl 24) or (ord(iv[m+2]) shl 16) or (ord(iv[m+3]) shl 8) or ord(iv[m+4]);
       cbcright := (ord(iv[m+5]) shl 24) or (ord(iv[m+6]) shl 16) or (ord(iv[m+7]) shl 8) or ord(iv[m+8]);
       m:=0;
     end;
   //loop through each 64 bit chunk of the message


  if    encrypt=1 then  len:=Length(smessage); //(加密也和c#一样)
   while m < len do
     begin
       left := (ord(smessage[m+1]) shl 24) or (ord(smessage[m+2]) shl 16) or (ord(smessage[m+3]) shl 8) or ord(smessage[m+4]);
       right := (ord(smessage[m+5]) shl 24) or (ord(smessage[m+6]) shl 16) or (ord(smessage[m+7]) shl 8) or ord(smessage[m+8]);
       m := m + 8;
       //for Cipher Block Chaining mode, xor the message with the previous result
       if mode = 1 then
         if encrypt=1 then
           begin
             left := left xor cbcleft;
             right := right xor cbcright;
           end
         else
           begin
             cbcleft2 := cbcleft;
             cbcright2 := cbcright;
             cbcleft := left;
             cbcright := right;
           end;
       //first each 64 but chunk of the message must be permuted according to IP
       temp := ((left shr 4) xor right) and $0f0f0f0f; right := right xor temp; left := left xor (temp shl 4);
       temp := ((left shr 16) xor right) and $0000ffff; right := right xor temp; left := left xor (temp shl 16);
       temp := ((right shr 2) xor left) and $33333333; left := left xor temp; right := right xor (temp shl 2);
       temp := ((right shr 8) xor left) and $00ff00ff; left := left xor temp; right := right xor (temp shl 8);
       temp := ((left shr 1) xor right) and $55555555; right := right xor temp; left := left xor (temp shl 1);
       left := ((left shl 1) or (left shr 31));
       right := ((right shl 1) or (right shr 31));
       //do this either 1 or 3 times for each chunk of the message
       j:=0;
       while j<iterations do
         begin
           endloop := looping[j+1];
           loopinc := looping[j+2];
           //now go through and perform the encryption or decryption
           i:= looping[j];
           while i<>endloop do
             begin
               right1 := right xor keys[i];
               right2 := ((right shr 4) or (right shl 28)) xor keys[i+1];
               //the result is attained by passing these bytes through the S selection functions
               temp := left;
               left := right;
               right := temp xor (spfunction2[(right1 shr 24) and $3f] or spfunction4[(right1 shr 16) and $3f]
                        or spfunction6[(right1 shr   8) and $3f] or spfunction8[right1 and $3f]
                        or spfunction1[(right2 shr 24) and $3f] or spfunction3[(right2 shr 16) and $3f]
                        or spfunction5[(right2 shr   8) and $3f] or spfunction7[right2 and $3f]);
               i:=i+loopinc;
             end;
           temp := left; left := right; right := temp; //unreverse left and right
           j:=j+3;
         end; //for either 1 or 3 iterations
       //move then each one bit to the right
       left := ((left shr 1) or (left shl 31));
       right := ((right shr 1) or (right shl 31));
       //now perform IP-1, which is IP in the opposite direction
       temp := ((left shr 1) xor right) and $55555555; right := right xor temp; left :=left xor (temp shl 1);
       temp := ((right shr 8) xor left) and $00ff00ff; left := left xor temp; right := right xor (temp shl 8);
       temp := ((right shr 2) xor left) and $33333333; left := left xor temp; right := right xor (temp shl 2);
       temp := ((left shr 16) xor right) and $0000ffff; right := right xor temp; left := left xor (temp shl 16);
       temp := ((left shr 4) xor right) and $0f0f0f0f; right := right xor temp; left := left xor (temp shl 4);
       //for Cipher Block Chaining mode, xor the message with the previous result
       if mode = 1 then
         if encrypt=1 then
           begin
           cbcleft := left; cbcright := right;
           end
         else
           begin
             left :=left xor cbcleft2;
             right := right xor cbcright2;
           end;
       tempresult := tempresult + chr(left shr 24) + chr((left shr 16) and $ff) + chr((left shr 8) and $ff) + chr(left and $ff) + chr(right shr 24) + chr((right shr 16) and $ff) + chr((right shr 8) and $ff) + chr(right and $ff);
        chunk := chunk + 8;
       if chunk = 512 then
         begin
           result := result + tempresult; tempresult := ''; chunk := 0;
         end;
     end; //for every 8 characters, or 64 bits in the message
   //return the result as an array
   result := result + tempresult;
end; //end of des




//des_createKeys
//this takes as input a 64 bit key (even though only 56 bits are used)
//as an array of 2 dwords, and returns 16 48 bit keys
function des_createKeys(key:string):fdArray;
const
   //declaring this locally speeds things up a bit
   pc2bytes0   :array[0..15] of dword= (0,$4,$20000000,$20000004,$10000,$10004,$20010000,$20010004,$200,$204,$20000200,$20000204,$10200,$10204,$20010200,$20010204);
   pc2bytes1   :array[0..15] of dword= (0,$1,$100000,$100001,$4000000,$4000001,$4100000,$4100001,$100,$101,$100100,$100101,$4000100,$4000101,$4100100,$4100101);
   pc2bytes2   :array[0..15] of dword= (0,$8,$800,$808,$1000000,$1000008,$1000800,$1000808,0,$8,$800,$808,$1000000,$1000008,$1000800,$1000808);
   pc2bytes3   :array[0..15] of dword= (0,$200000,$8000000,$8200000,$2000,$202000,$8002000,$8202000,$20000,$220000,$8020000,$8220000,$22000,$222000,$8022000,$8222000);
   pc2bytes4   :array[0..15] of dword= (0,$40000,$10,$40010,0,$40000,$10,$40010,$1000,$41000,$1010,$41010,$1000,$41000,$1010,$41010);
   pc2bytes5   :array[0..15] of dword= (0,$400,$20,$420,0,$400,$20,$420,$2000000,$2000400,$2000020,$2000420,$2000000,$2000400,$2000020,$2000420);
   pc2bytes6   :array[0..15] of dword= (0,$10000000,$80000,$10080000,$2,$10000002,$80002,$10080002,0,$10000000,$80000,$10080000,$2,$10000002,$80002,$10080002);
   pc2bytes7   :array[0..15] of dword= (0,$10000,$800,$10800,$20000000,$20010000,$20000800,$20010800,$20000,$30000,$20800,$30800,$20020000,$20030000,$20020800,$20030800);
   pc2bytes8   :array[0..15] of dword= (0,$40000,0,$40000,$2,$40002,$2,$40002,$2000000,$2040000,$2000000,$2040000,$2000002,$2040002,$2000002,$2040002);
   pc2bytes9   :array[0..15] of dword= (0,$10000000,$8,$10000008,0,$10000000,$8,$10000008,$400,$10000400,$408,$10000408,$400,$10000400,$408,$10000408);
   pc2bytes10 :array[0..15] of dword= (0,$20,0,$20,$100000,$100020,$100000,$100020,$2000,$2020,$2000,$2020,$102000,$102020,$102000,$102020);
   pc2bytes11 :array[0..15] of dword= (0,$1000000,$200,$1000200,$200000,$1200000,$200200,$1200200,$4000000,$5000000,$4000200,$5000200,$4200000,$5200000,$4200200,$5200200);
   pc2bytes12 :array[0..15] of dword= (0,$1000,$8000000,$8001000,$80000,$81000,$8080000,$8081000,$10,$1010,$8000010,$8001010,$80010,$81010,$8080010,$8081010);
   pc2bytes13 :array[0..15] of dword= (0,$4,$100,$104,0,$4,$100,$104,$1,$5,$101,$105,$1,$5,$101,$105);
    //now define the left shifts which need to be done
   shifts :array[0..15] of dword = (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
var
   iterations:integer;
   keys:fdArray;
   lefttemp, righttemp, temp:dword;
   m, n, j,i:integer;
   left,right:dword;
begin
   //how many iterations (1 for des, 3 for triple des)
   if length(key) = 24 then
     iterations := 3
   else
     iterations := 1;
   //stores the return keys
   setlength(keys,32 * iterations);
   //other variables
   m:=0;n:=0;
   for j:=0 to iterations-1 do //either 1 or 3 iterations
     begin
       left := (ord(key[m+1]) shl 24) or (ord(key[m+2]) shl 16) or (ord(key[m+3]) shl 8) or ord(key[m+4]);
       right := (ord(key[m+5]) shl 24) or (ord(key[m+6]) shl 16) or (ord(key[m+7]) shl 8) or ord(key[m+8]);
       m:=m+8;
       temp := ((left shr 4) xor right) and $0f0f0f0f; right :=right xor temp; left :=left xor (temp shl 4);
       temp := ((right shr 16) xor left) and $0000ffff; left := left xor temp; right :=right xor (temp shl 16);
       temp := ((left shr 2) xor right) and $33333333; right :=right xor temp; left := left xor (temp shl 2);
       temp := ((right shr 16) xor left) and $0000ffff; left :=left xor temp; right := right xor (temp shl 16);
       temp := ((left shr 1) xor right) and $55555555; right := right xor temp; left := left xor (temp shl 1);
       temp := ((right shr 8) xor left) and $00ff00ff; left :=left xor temp; right := right xor (temp shl 8);
       temp := ((left shr 1) xor right) and $55555555; right :=right xor temp; left := left xor (temp shl 1);
       //the right side needs to be shifted and to get the last four bits of the left side
       temp := (left shl 8) or ((right shr 20) and $000000f0);
       //left needs to be put upside down
       left := (right shl 24) or ((right shl 8) and $ff0000) or ((right shr 8) and $ff00) or ((right shr 24) and $f0);
       right := temp;
       //now go through and perform these shifts on the left and right keys
       for i:=low(shifts) to   high(shifts) do
         begin
           //shift the keys either one or two bits to the left
           if shifts[i] > 0 then
             begin
               left := (left shl 2) or (left shr 26);
               right := (right shl 2) or (right shr 26);
               //left := left shl 0;
               //right:= right shl 0;
             end
           else
             begin
               left := (left shl 1) or (left shr 27);
               right := (right shl 1) or (right shr 27);
               //left := left shl 0;
               //right:= right shl 0;
             end;
           left := left and $fffffff0;
           right:= right and $fffffff0;
           //now apply PC-2, in such a way that E is easier when encrypting or decrypting
           //this conversion will look like PC-2 except only the last 6 bits of each byte are used
           //rather than 48 consecutive bits and the order of lines will be according to
           //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
           lefttemp := pc2bytes0[left shr 28] or pc2bytes1[(left shr 24) and $f]
                       or pc2bytes2[(left shr 20) and $f] or pc2bytes3[(left shr 16) and $f]
                       or pc2bytes4[(left shr 12) and $f] or pc2bytes5[(left shr 8) and $f]
                       or pc2bytes6[(left shr 4) and $f];
           righttemp := pc2bytes7[right shr 28] or pc2bytes8[(right shr 24) and $f]
                        or pc2bytes9[(right shr 20) and $f] or pc2bytes10[(right shr 16) and $f]
                        or pc2bytes11[(right shr 12) and $f] or pc2bytes12[(right shr 8) and $f]
                        or pc2bytes13[(right shr 4) and $f];
           temp := ((righttemp shr 16) xor lefttemp) and $0000ffff;
           keys[n+0] := lefttemp xor temp;
           keys[n+1] := righttemp xor (temp shl 16);
           n:=n+2;
         end;
     end; //for each iterations
   //return the keys we've created
   Result := keys;
end;//end of des_createKeys




function StrToHex(Str:string):string;
var
   i:integer;
begin
   result := '';
   for i := 1 to length(Str) do
     result := result + IntToHex(Ord(Str[i]),2);
end;


function HexToStr(Hex:string):string;
var
   i:Integer;
begin
   Result := '';
   for i := 1 to length(Hex) div 2 do
     if IsInt('$' + Hex[i * 2 - 1] + Hex[i * 2]) then
       Result := Result + Chr(StrToInt('$' + Hex[i * 2 - 1] + Hex[i * 2]));
end;


function IsInt(Str:String):Boolean;
begin
   result := True;
   try
     StrToInt(Str);
   except
     result := False
   end;
end;




{function EncryStr_3DES(Str, Key: String): String;
var s  ,StrResult, TempResult, Temp: String;
 I: Integer;
begin
  if Length(Key) < 16 then
    while Length(Key) < 16 do
      Key := Key + Chr(0);
   s := EncryStrHex(Str, Copy(Key, 1, 8));
   s := DecryStrHex(s, Copy(Key, 9, 8));
   s := EncryStrHex(s, Copy(Key, 1, 8));
      Result := s;
end;  }


end.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
unit dmdes; {*********************************************************} {* DELPHIPHPC#通用DES编码解码单元 *} {* 由TurboPower LockBox部分代码改写 *} {* 滕州市东鸣软件工作室制作 ZWF 2011-12-27 *} {*********************************************************} {EncryDes编码函数,DecryDes解码函数,keystr为密码,ivstr为偏移量, 一般设置keystr,ivstr相同,内容为八位字节长度的字符串,编码结果为十六进制字串} interface uses Windows,SysUtils; type PKey64 = ^TKey64; TKey64 = array [0..7] of Byte; type TDESBlock = array[0..7] of Byte; TDESContext = packed record TransformedKey : array [0..31] of LongInt; Encrypt : Boolean; end; function EncryDes(const str:string;const keystr:string;const ivstr:string):string ; function DecryDes(const str:string;const keystr:string;const ivstr:string):string ; implementation procedure XorMemPrim(var Mem1; const Mem2; Count : Cardinal); register; asm push esi push edi mov esi, eax //esi = Mem1 mov edi, edx //edi = Mem2 push ecx //save byte count shr ecx, 2 //convert to dwords jz @Continue cld @Loop1: //xor dwords at a time mov eax, [edi] xor [esi], eax add esi, 4 add edi, 4 dec ecx jnz @Loop1 @Continue: //handle remaining bytes (3 or less) pop ecx and ecx, 3 jz @Done @Loop2: //xor remaining bytes mov al, [edi] xor [esi], al inc esi inc edi dec ecx jnz @Loop2 @Done: pop edi pop esi end; { -------------------------------------------------------------------------- } procedure XorMem(var Mem1; const Mem2; Count : Cardinal); begin XorMemPrim(Mem1, Mem2, Count); end; { -------------------------------------------------------------------------- } procedure EncryptDES(const Context : TDESContext; var Block : TDESBlock); const SPBox : array [0..7, 0..63] of DWord = (($01010400, $00000000, $00010000, $01010404, $01010004, $00010404, $00000004, $00010000, $00000400, $01010400, $01010404, $00000400, $01000404, $01010004, $01000000, $00000004, $00000404, $01000400, $01000400, $00010400, $00010400, $01010000, $01010000, $01000404, $00010004, $01000004, $01000004, $00010004, $00000000, $00000404, $00010404, $01000000, $00010000, $01010404, $00000004, $01010000, $01010400, $01000000, $01000000, $00000400, $01010004, $00010000, $00010400, $01000004, $00000400, $00000004, $01000404, $00010404, $01010404, $00010004, $01010000, $01000404, $01000004, $00000404, $00010404, $01010400, $00000404, $01000400, $01000400, $00000000, $00010004, $00010400, $00000000, $01010004), ($80108020, $80008000, $00008000, $00108020, $00100000, $00000020, $80100020, $80008020, $80000020, $80108020, $80108000, $80000000, $80008000, $00100000, $00000020, $80100020, $00108000, $00100020, $80008020, $00000000, $80000000, $00008000, $00108020, $80100000, $00100020, $80000020, $00000000, $00108000, $00008020, $80108000, $80100000, $00008020, $00000000, $00108020, $80100020, $00100000, $80008020, $80100000, $80108000, $00008000, $80100000, $80008000, $00000020, $80108020, $00108020, $00000020, $00008000, $80000000, $00008020, $80108000, $00100000, $80000020, $00100020, $80008020, $80000020, $00100020, $00108000, $00000000, $80008000, $00008020, $80000000, $80100020, $80108020, $00108000), ($00000208, $08020200, $00000000, $08020008, $08000200, $00000000, $00020208, $08000200, $00020008, $08000008, $08000008, $00020000, $08020208, $00020008, $08020000, $00000208, $08000000, $00000008, $08020200, $00000200, $00020200, $08020000, $08020008, $00020208, $08000208, $00020200, $00020000, $08000208, $00000008, $08020208, $00000200, $08000000, $08020200, $08000000, $00020008, $00000208, $00020000, $08020200, $08000200, $00000000, $00000200, $00020008, $08020208, $08000200, $08000008, $00000200, $00000000, $08020008, $08000208, $00020000, $08000000, $08020208, $00000008, $00020208, $00020200, $08000008, $08020000, $08000208, $00000208, $08020000, $00020208, $00000008, $08020008, $00020200), ($00802001, $00002081, $00002081, $00000080, $00802080, $00800081, $00800001, $00002001, $00000000, $00802000, $00802000, $00802081, $00000081, $00000000, $00800080, $00800001, $00000001, $00002000, $00800000, $00802001, $00000080, $00800000, $00002001, $00002080, $00800081, $00000001, $00002080, $00800080, $00002000, $00802080, $00802081, $00000081, $00800080, $00800001, $00802000, $00802081, $00000081, $00000000, $00000000, $00802000, $00002080, $00800080, $00800081, $00000001, $00802001, $00002081, $00002081, $00000080, $00802081, $00000081, $00000001, $00002000, $00800001, $00002001, $00802080, $00800081, $00002001, $00002080, $00800000, $00802001, $00000080, $00800000, $00002000, $00802080), ($00000100, $02080100, $02080000, $42000100, $00080000, $00000100, $40000000, $02080000, $40080100, $00080000, $02000100, $40080100, $42000100, $42080000, $00080100, $40000000, $02000000, $40080000, $40080000, $00000000, $40000100, $42080100, $42080100, $02000100, $42080000, $40000100, $00000000, $42000000, $02080100, $02000000, $42000000, $00080100, $00080000, $42000100, $00000100, $02000000, $40000000, $02080000, $42000100, $40080100, $02000100, $40000000, $42080000, $02080100, $40080100, $00000100, $02000000, $42080000, $42080100, $00080100, $42000000, $42080100, $02080000, $00000000, $40080000, $42000000, $00080100, $02000100, $40000100, $00080000, $00000000, $40080000, $02080100, $40000100), ($20000010, $20400000, $00004000, $20404010, $20400000, $00000010, $20404010, $00400000, $20004000, $00404010, $00400000, $20000010, $00400010, $20004000, $20000000, $00004010, $00000000, $00400010, $20004010, $00004000, $00404000, $20004010, $00000010, $20400010, $20400010, $00000000, $00404010, $20404000, $00004010, $00404000, $20404000, $20000000, $20004000, $00000010, $20400010, $00404000, $20404010, $00400000, $00004010, $20000010, $00400000, $20004000, $20000000, $00004010, $20000010, $20404010, $00404000, $20400000, $00404010, $20404000, $00000000, $20400010, $00000010, $00004000, $20400000, $00404010, $00004000, $00400010, $20004010, $00000000, $20404000, $20000000, $00400010, $20004010), ($00200000, $04200002, $04000802, $00000000, $00000800, $04000802, $00200802, $04200800, $04200802, $00200000, $00000000, $04000002, $00000002, $04000000, $04200002, $00000802, $04000800, $00200802, $00200002, $04000800, $04000002, $04200000, $04200800, $00200002, $04200000, $00000800, $00000802, $04200802, $00200800, $00000002, $04000000, $00200800, $04000000, $00200800, $00200000, $04000802, $04000802, $04200002, $04200002, $00000002, $00200002, $04000000, $04000800, $00200000, $04200800, $00000802, $00200802, $04200800, $00000802, $04000002, $04200802, $04200000, $00200800, $00000000, $00000002, $04200802, $00000000, $00200802, $04200000, $00000800, $04000002, $04000800, $00000800, $00200002), ($10001040, $00001000, $00040000, $10041040, $10000000, $10001040, $00000040, $10000000, $00040040, $10040000, $10041040, $00041000, $10041000, $00041040, $00001000, $00000040, $10040000, $10000040, $10001000, $00001040, $00041000, $00040040, $10040040, $10041000, $00001040, $00000000, $00000000, $10040040, $10000040, $10001000, $00041040, $00040000, $00041040, $00040000, $10041000, $00001000, $00000040, $10040040, $00001000, $00041040, $10001000, $00000040, $10000040, $10040000, $10040040, $10000000, $00040000, $10001040, $00000000, $10041040, $00040040, $10000040, $10040000, $10001000, $10001040, $00000000, $10041040, $00041000, $00041000, $00001040, $00001040, $00040040, $10000000, $10041000)); var I, L, R, Work : DWord; CPtr : PDWord; procedure SplitBlock(const Block : TDESBlock; var L, R : DWord); register; asm push ebx push eax mov eax, [eax] mov bh, al mov bl, ah rol ebx, 16 shr eax, 16 mov bh, al mov bl, ah mov [edx], ebx pop eax mov eax, [eax+4] mov bh, al mov bl, ah rol ebx, 16 shr eax, 16 mov bh, al mov bl, ah mov [ecx], ebx pop ebx end; procedure JoinBlock(const L, R : LongInt; var Block : TDESBlock); register; asm push ebx mov bh, al mov bl, ah rol ebx, 16 shr eax, 16 mov bh, al mov bl, ah mov [ecx+4], ebx mov bh, dl mov bl, dh rol ebx, 16 shr edx, 16 mov bh, dl mov bl, dh mov [ecx], ebx pop ebx end; procedure IPerm(var L, R : DWord); var Work : DWord; begin Work := ((L shr 4) xor R) and $0F0F0F0F; R := R xor Work; L := L xor Work shl 4; Work := ((L shr 16) xor R) and $0000FFFF; R := R xor Work; L := L xor Work shl 16; Work := ((R shr 2) xor L) and $33333333; L := L xor Work; R := R xor Work shl 2; Work := ((R shr 8) xor L) and $00FF00FF; L := L xor Work; R := R xor Work shl 8; R := (R shl 1) or (R shr 31); Work := (L xor R) and $AAAAAAAA; L := L xor Work; R := R xor Work; L := (L shl 1) or (L shr 31); end; procedure FPerm(var L, R : DWord); var Work : DWord; begin L := L; R := (R shl 31) or (R shr 1); Work := (L xor R) and $AAAAAAAA; L := L xor Work; R := R xor Work; L := (L shr 1) or (L shl 31); Work := ((L shr 8) xor R) and $00FF00FF; R := R xor Work; L := L xor Work shl 8; Work := ((L shr 2) xor R) and $33333333; R := R xor Work; L := L xor Work shl 2; Work := ((R shr 16) xor L) and $0000FFFF; L := L xor Work; R := R xor Work shl 16; Work := ((R shr 4) xor L) and $0F0F0F0F; L := L xor Work; R := R xor Work shl 4; end; begin SplitBlock(Block, L, R); IPerm(L, R); CPtr := @Context; for I := 0 to 7 do begin Work := (((R shr 4) or (R shl 28)) xor CPtr^); Inc(CPtr); L := L xor SPBox[6, Work and $3F]; L := L xor SPBox[4, Work shr 8 and $3F]; L := L xor SPBox[2, Work shr 16 and $3F]; L := L xor SPBox[0, Work shr 24 and $3F]; Work := (R xor CPtr^); Inc(CPtr); L := L xor SPBox[7, Work and $3F]; L := L xor SPBox[5, Work shr 8 and $3F]; L := L xor SPBox[3, Work shr 16 and $3F]; L := L xor SPBox[1, Work shr 24 and $3F]; Work := (((L shr 4) or (L shl 28)) xor CPtr^); Inc(CPtr); R := R xor SPBox[6, Work and $3F]; R := R xor SPBox[4, Work shr 8 and $3F]; R := R xor SPBox[2, Work shr 16 and $3F]; R := R xor SPBox[0, Work shr 24 and $3F]; Work := (L xor CPtr^); Inc(CPtr); R := R xor SPBox[7, Work and $3F]; R := R xor SPBox[5, Work shr 8 and $3F]; R := R xor SPBox[3, Work shr 16 and $3F]; R := R xor SPBox[1, Work shr 24 and $3F]; end; FPerm(L, R); JoinBlock(L, R, Block); end; procedure InitEncryptDES(const Key : TKey64; var Context : TDESContext; Encrypt : Boolean); const PC1 : array [0..55] of Byte = (56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3); PC2 : array [0..47] of Byte = (13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31); CTotRot : array [0..15] of Byte = (1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28); CBitMask : array [0..7] of Byte = (128, 64, 32, 16, 8, 4, 2, 1); var PC1M : array [0..55] of Byte; PC1R : array [0..55] of Byte; KS : array [0..7] of Byte; I, J, L, M : LongInt; begin {convert PC1 to bits of key} for J := 0 to 55 do begin L := PC1[J]; M := L mod 8; PC1M[J] := Ord((Key[L div 8] and CBitMask[M]) 0); end; {key chunk for each iteration} for I := 0 to 15 do begin {rotate PC1 the right amount} for J := 0 to 27 do begin L := J + CTotRot[I]; if (L (length(keystr)-1) then key[i] :=0 else key[i] := byte(keystr[i+1]); end; for i:=0 to 15 do begin if i > (length(ivstr)-1) then iv[i]:=0 else iv[i] := byte(ivstr[i+1]); end; InitEncryptDES(Key, Context, true); len := length(AnsiString(str)); xx:= char( 8- (len mod 8)); for i:=0 to round(len/8) do begin for j:=0 to 7 do begin if ((i*7+j+1) (length(keystr)-1) then key[i] :=0 else key[i] := byte(keystr[i+1]); end; for i:=0 to 15 do begin if i > (length(ivstr)-1) then iv[i]:=0 else iv[i] := byte(ivstr[i+1]); end; InitEncryptDES(Key, Context, false); res:=''; for j:= 0 to (length(str) div 2)-1 do begin lss:=copy(str,j*2+1,2); res:=res+ char(StrToInt('$'+lss)) ; end; len := length(AnsiString(res)); for i:=0 to round(len/8)-1 do begin for j:=0 to 7 do begin if ((i*7+j+1)<=len) then begin poschar:=res[i*8+j+1]; block[j]:=byte(poschar); end else begin block[j]:=byte(xx); end; end; bak:=block; EncryptDESCBC(Context, IV, Block); for j:= 0 to 7 do begin result := result + char(block[j]); end; iv:=bak; end; end; end.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值