⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit1.pas

📁 des 3des加密delphi例子;标准的des,3des算法
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,Math;
 // initial permutation (IP)   数据处理IP置换
const
  IP_Table :array[0..63]of Integer =(
	58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
	62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
	57, 49, 41, 33, 25, 17,  9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
  61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7);

  PC1_Table:array[0..55]of Integer = (
	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);

  // number left rotations of pc1
  Shift_Table:array[0..15]of Integer = (
	1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1);

  // permuted choice key (PC2)
  PC2_Table:array[0..47]of Integer = (
	14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,
	23, 19, 12,  4, 26,  8, 16,  7, 27, 20, 13,  2,
	41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
	44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32);

  // expansion operation matrix (E)
  E_Table:array[0..47]of Integer =(32,  1,  2,  3,  4,  5,  4,  5,  6,  7,  8,  9,
	 8,  9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
	16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
	24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32,  1);

  // final permutation IP^-1 
  IPR_Table:array[0..63]of Char =(
	Char(40), Char(8), Char(48), Char(16), Char(56), Char(24), Char(64), Char(32), Char(39),
  Char(7), Char(47), Char(15), Char(55), Char(23), Char(63), Char(31),Char(38), Char(6),
  Char(46), Char(14), Char(54), Char(22), Char(62), Char(30), Char(37), Char(5), Char(45),
  Char(13), Char(53), Char(21), Char(61), Char(29), Char(36), Char(4), Char(44), Char(12),
  Char(52), Char(20), Char(60), Char(28), Char(35), Char(3), Char(43), Char(11), Char(51),
  Char(19), Char(59), Char(27), Char(34), Char(2), Char(42), Char(10), Char(50), Char(18),
  Char(58), Char(26), Char(33), Char(1), Char(41),  Char(9), Char(49), Char(17), Char(57), Char(25));

  // 32-bit permutation function P used on the output of the S-boxes 
  P_Table:array[0..31]of Char = (
	Char(16), Char(7), Char(20), Char(21), Char(29), Char(12), Char(28),
  Char(17), Char(1),  Char(15), Char(23), Char(26), Char(5),  Char(18),
  Char(31), Char(10), Char(2),  Char(8), Char(24), Char(14), Char(32),
  Char(27), Char(3),  Char(9),  Char(19), Char(13), Char(30), Char(6),
  Char(22), Char(11), Char(4),  Char(25));

// The (in)famous S-boxes
  S_Box:array[0..7]of array[0..3,0..15]of Integer = (
  //S1
   ((14,  4,	13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7),
	 (0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8),
	 (4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0),
   (15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13)),

	// S2
  ((15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10),
	 (3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5),
	 (0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15),
   (13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9)),

	// S3
  ((10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8),
	(13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1),
	(13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7),
  (1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12)),
	// S4
  ((7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15),
	(13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9),
	(10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4),
  (3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14)),
	// S5
  ((2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9),
	(14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6),
	 (4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14),
   (11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3)),
	// S6
  ((12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11),
	(10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8),
	 (9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6),
   (4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13)),
	// S7
  ((4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1),
	(13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6),
	 (1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2),
   (6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12)),
	// S8
  ((13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7),
	 (1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2),
	 (7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8),
   (2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11)));
type
  TSubKey = array[0..15,0..47]of Char;


type
  TForm1 = class(TForm)
    btn1: TButton;
    edt2: TEdit;
    lbl1: TLabel;
    edt3: TEdit;
    lbl2: TLabel;
    lbl3: TLabel;
    btn4: TButton;
    edt4: TEdit;
    lbl4: TLabel;
    lbl5: TLabel;
    btn2: TButton;
    edt1: TEdit;
    lbl6: TLabel;
    btn3: TButton;
    edt5: TEdit;
    btn5: TButton;
    procedure btn1Click(Sender: TObject);
    procedure btn3Click(Sender: TObject);
    procedure btn4Click(Sender: TObject);
    procedure btn2Click(Sender: TObject);
    procedure btn5Click(Sender: TObject);
  private
    { Private declarations }
    SubKeys:TSubKey; //array[0..15,0..47]of Char;//储存16组48位密钥
    SubKeys2:TSubKey;//array[0..15,0..47]of Char;//储存16组48位密钥

    szCiphertext:array[0..15]of Char;//储存16位密文(十六进制字符串)
    szPlaintext:array[0..7]of Char;//储存8位明文字符串
    szFCiphertextAnyLength:array[0..8191]of Char;//任意长度密文(十六进制字符串)
    szFPlaintextAnyLength:array[0..4095]of Char;//任意长度明文字符串
//    szFPlaintextAnyLength:array[0..4095]of Char ;//任意长度明文字符串

    function FillToEightBits(var sz:string):Boolean;
    function SingleBinaryToChar(iTmp:Integer):Char;
    function SingleCharToBinary(ch:Char):Integer;
    function CreateSubKey(sz:array of Char;var reSubKey:TSubKey):Boolean;
    function EncryptAnyLength(szSource:string;bIsUseSecondKey:Boolean):Boolean;
    function EncryptData(s:string;bIsUseSecondKey,bShowResultInHex:Boolean):Boolean;
    function GetCiphertextAnyLength:string;
    function InitialPermuteData(s:string;var sz:array of Char;szBool:Boolean):Boolean;

    //--------------------------------------------------------------
    //功能:DES中的F函数,
    //参数:左32位,右32位,key序号(0-15)
    //结果:均在变换左右32位
    //--------------------------------------------------------------
     procedure FunctionF(var sz_Li1, sz_Ri1:array of Char;bIsUseSecondKey:Boolean;iKey:Integer);


     //--------------------------------------------------------------
    //功能:将右32位进行扩展位48位,
    //参数:原32位字符串,扩展后结果存放指针
    //结果:函数改变第二个参数的内容
    //--------------------------------------------------------------
     procedure ExpansionR(var rsData,deData:array of Char);

    //--------------------------------------------------------------
    //功能:异或函数,
    //参数:待异或的操作字符串1,字符串2,操作数长度,处理后结果存放指针
    //结果: 函数改变第四个参数的内容
    //--------------------------------------------------------------
    procedure ExecXOR(sz_P1,sz_P2:array of Char;len:Integer; var Return_value:array of Char);

    //--------------------------------------------------------------
    //功能:S-BOX , 数据压缩,
    //参数:48位二进制字符串,
    //结果:返回结果:32位字符串
    //--------------------------------------------------------------
    function CompressFuncS(sz_48:array of Char):string;

    //--------------------------------------------------------------
    //功能:IP逆变换,
    //参数:待变换字符串,处理后结果存放指针
    //结果:函数改变第二个参数的内容
    //--------------------------------------------------------------
   procedure PermutationP(s:string;var Return_value:array of Char);

    //--------------------------------------------------------------
    //功能:16进制整数(0-15)到2进制字符串的转换
    //参数:十六进制整数(0-15)
    //结果:返回二进制字符串("0000"-"1111")
    //--------------------------------------------------------------
  function HexIntToBinary(i:Integer ):string;

  function MyPower(base,Exponent:Integer):Integer;

  //--------------------------------------------------------------
  //功能:二进制串到字符串的转换,
  //参数:源二进制字符串,二进制字符串长度,类型(true为二进制到hex,false为二进制到ANSCII char),
  //结果:返回处理后结果
  //--------------------------------------------------------------
  function BinaryToString(szSource:array of Char; len:Integer;bType:Boolean):string;
  //--------------------------------------------------------------
  //功能:解密任意长度十六进制字符串
  //参数:任意长度字符串
  //结果:函数将加密后结果存放于private szFPlaintextAnyLength[4096]
  //      用户通过属性PlaintextAnyLength得到
  //--------------------------------------------------------------
  function DecryptAnyLength( sHexData:string;bIsUseSecondKey:Boolean):Boolean;

  //--------------------------------------------------------------
  //功能:解密16位十六进制字符串
  //参数:16位十六进制字符串
  //结果:函数将解密候结果存放于private szPlaintext[8]
  //      用户通过属性Plaintext得到
  //--------------------------------------------------------------
  function DecryptData(s:string;bIsUseSecondKey,bDecryptHex:Boolean):Boolean;


  function  HexCharToBinary(ch:Char):string;

  //--------------------------------------------------------------
  //功能:使用3DES加密任意长度字符串
  //参数:任意长度字符串
  //结果:函数将加密后结果存放于private szFCiphertextAnyLength[8192]
  //      用户通过属性CiphertextAnyLength得到
  //--------------------------------------------------------------
  procedure TripleEncryptAnyLength(szSource:string);

  //--------------------------------------------------------------
  //功能:使用3DES解密任意长度十六进制字符串
  //参数:任意长度字符串
  //结果:函数将加密后结果存放于private szFPlaintextAnyLength[4096]
  //      用户通过属性PlaintextAnyLength得到
  //--------------------------------------------------------------
  procedure TripleDecryptAnyLength(szSource:string);

  public
    { Public declarations }
    procedure InitializeKey(sKey:string;isScndKey:Boolean);  //处理密钥
  end;

var
  Form1: TForm1;

implementation

uses Des3DesPrg;

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
begin
  edt4.Text := '';
  FillChar(SubKeys,SizeOf(SubKeys),$0);
  FillChar(SubKeys2,SizeOf(SubKeys2),$0);
  InitializeKey(Trim(edt1.Text),False);  //变换密钥
  EncryptAnyLength(Trim(edt3.Text),False);
  edt5.Text :=GetCiphertextAnyLength();
end;

function TForm1.SingleBinaryToChar(iTmp:Integer): Char;
begin
  if iTmp=1 then
    Result:= '1'
  else
    Result:='0';
end;

procedure TForm1.btn3Click(Sender: TObject);

begin

  TripleDecryptAnyLength(edt5.Text);
  edt4.Text := szFPlaintextAnyLength;
end;

procedure TForm1.InitializeKey(sKey: string;isScndKey:Boolean);
var
  sz_64key:array[0..63]of Char;
  iTmpBit:array[0..63]of Integer;
  sz_56Key:array[0..55]of Char;
  i,j,it:Integer;
begin
  FillChar(iTmpBit,SizeOf(iTmpBit),0);
  FillChar(sz_64key,SizeOf(sz_64key),' ');
  FillChar(sz_56Key,SizeOf(sz_56Key),' ');
  //convert 8 char-bytes key to 64 binary-bits    把8字节的密钥转换为64位的二进制bits
  for i:=0 to 63 do
  begin
    it := i shr 3;                  
    if it<Length(sKey) then
      iTmpBit[i] := (Ord(sKey[it+1])shr(i and 7))and 1
    else
      iTmpBit[i] := 0;
      //a = 0x61 = 0110,0001
      //after this , a is 1000,0110

  end;
//  let me convert it to right
  for i:=0 to 7 do
  begin
    for j:=0 to 7 do
      sz_64key[8*i+j] := SingleBinaryToChar(iTmpBit[8*(i+1)-(j+1)]);
  end;
  // 舍弃64位密钥中的奇偶校验位,然后按PC1置换

  for i:=0 to 55 do
  begin
    sz_56Key[i] := sz_64key[PC1_Table[i]-1];

  end;
  if isScndKey then
    CreateSubKey(sz_56Key,SubKeys2)
  else
    CreateSubKey(sz_56Key,SubKeys);
end;

function TForm1.CreateSubKey(sz:array of Char;var reSubKey:TSubKey): Boolean;
var
  szCi,szDi,szTmpR,szTmpL:array[0..27] of Char;
  szTmp56:array[0..55] of Char;
  i,j:Integer;
begin
  FillChar(szTmpL,SizeOf(szTmpL),$0);
  FillChar(szTmpR,SizeOf(szTmpR),$0);
  FillChar(szCi,SizeOf(szCi),$0);
  FillChar(szDi,SizeOf(szDi),$0);
  //把56位密钥分解为两部分
  CopyMemory(@szTmpL[0],@sz[0],28);
  CopyMemory(@szTmpR[0],@sz[28],28);
  {生成16个子密钥,初始I=1。 
 1-2-3-1、同时将C[I]、D[I]左移1位或2位,根据I值决定左移的位数。见下表 
 I: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 
 左移位数: 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1}
  for i:=0 to 15 do
  begin
    //shift to left
    //Left 28 bits
    CopyMemory(@szCi,@szTmpL[Shift_Table[i]],28-Shift_Table[i]);
    CopyMemory(@szCi[28-Shift_Table[i]],@szTmpL,Shift_Table[i]);
    //Right 28 bits
    CopyMemory(@szDi,@szTmpR[Shift_Table[i]],28 - Shift_Table[i]);
    CopyMemory(@szDi[28 - Shift_Table[i]],@szTmpR,Shift_Table[i]);
    //permuted choice 48 bits key
    CopyMemory(@szTmp56,@szCi,28);
    CopyMemory(@szTmp56[28],@szDi,28);
    for j:=0 to 47 do
    begin
      reSubKey[i][j] := szTmp56[PC2_Table[j]-1]
    end;
    CopyMemory(@szTmpL,@szCi,28);
    CopyMemory(@szTmpR,@szDi,28);
  end;
  Result := True;
end;

function TForm1.EncryptAnyLength(szSource: string;bIsUseSecondKey:Boolean): Boolean;
var
  iLength,iParts,iResidue,i:Integer;
  szLast8Bits,szTmp:string;
begin
  iLength := Length(szSource);
  if iLength = 8 then
  begin
    EncryptData(szSource,bIsUseSecondKey,true);
    CopyMemory(@szFCiphertextAnyLength,@szCiphertext,16);
    //set the last char to '\0'
    szFCiphertextAnyLength[16] := Char($0);
  end
  else
  if iLength<8 then
  begin
    FillToEightBits(szSource);
    EncryptData(szSource,bIsUseSecondKey,true);
    CopyMemory(@szFCiphertextAnyLength,@szCiphertext,16);
    //set the last char to '\0'
    szFCiphertextAnyLength[16] := Char($0);

  end
  else
  if iLength>8 then
  begin

    iParts := ceil(iLength/8.0);   //使用ceil函数。ceil(x)返回的是大于x的最小整数
    iResidue := iLength mod 8;
    //encrypt the data 8 by 8 except the last part
    for i:=0 to (iParts-2) do
    begin
      szTmp := Copy(szSource,(i*8)+1,8);
      EncryptData(szTmp,bIsUseSecondKey,true);
      //after call EncryptData
      //cpoy the temp result to szFCiphertextAnyLength
      CopyMemory(@szFCiphertextAnyLength[16*i],@szCiphertext,16);
      if iResidue<>0 then //can't be divided exactly by 8
      begin
        szLast8Bits := Copy(szSource,(iParts-1)*8+1,iResidue);
        FillToEightBits(szLast8Bits);
      end
      else  //be divided exactly by 8
        szLast8Bits := Copy(szSource,(iParts-1)*8+1,8);

      //encrypt the last part
      EncryptData(szLast8Bits,bIsUseSecondKey,true);
      CopyMemory(@szFCiphertextAnyLength[16*(iParts - 1)],@szCiphertext,16);
      //set the last char to '\0'
      szFCiphertextAnyLength[(iParts)*16] := Char($0);
    end;
  end;
  Result := True;
end;

function TForm1.EncryptData(s: string;bIsUseSecondKey,bShowResultInHex:Boolean): Boolean;
var
  iCnt:Integer;
  sz_Li,sz_Ri:array[0..31] of Char;
  sz_IP,sz_Final64,szCiphertextBinary:array[0..63] of Char;
begin
  FillChar(sz_IP,SizeOf(sz_IP),$0);
  FillChar(sz_Final64,SizeOf(sz_Final64),$0);
  FillChar(szCiphertextBinary,SizeOf(szCiphertextBinary),$0);

  //IP
  InitialPermuteData(s,sz_IP,true);
  //分成两部份
  FillChar(sz_Li,SizeOf(sz_Li),$0);
  FillChar(sz_Ri,SizeOf(sz_Ri),$0);
  CopyMemory(@sz_Li[0],@sz_IP[0],32);
  CopyMemory(@sz_Ri[0],@sz_IP[32],32);

  for iCnt:=0 to 15 do
    FunctionF(sz_Li,sz_Ri,bIsUseSecondKey,iCnt);

  CopyMemory(@sz_Final64,@sz_Ri,32);
  CopyMemory(@sz_Final64[32],@sz_Li,32);
 //~IP

  iCnt := 0;
//  for iCnt := 0 to 63 do
  while iCnt <64 do            //按*P置换
  begin
    szCiphertextBinary[iCnt] := sz_Final64[Ord(IPR_Table[iCnt])-1];
    Inc(iCnt);
  end;
  CopyMemory(@szCiphertext,PChar(BinaryToString(szCiphertextBinary,64,true)),16);
  Result := True;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -