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

📄 rc_rndcrypt.pas

📁 Rijndael algorithm修正了CBC下BUG的版本(有源代码)工作在:D5。作者:Sergey Kirichenko。
💻 PAS
字号:
(* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                ---------------------------------                *
 *                            DELPHI                               *
 *                    Rijndael Extended API                        *
 *                          version 1.0                            *
 *                ---------------------------------                *
 *                                                   December 2000 *
 *                                                                 *
 * Author: Sergey Kirichenko (ksv@cheerful.com)                    *
 * Home Page: http://rcolonel.tripod.com                           *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *)

unit rc_rndcrypt;

interface

uses sysutils,
     rijndael_api_ref;

const
  _KEYLength = 128;

function ExpandKey(sKey: string; iLength: integer): string;
{encode string}
function EnCryptString(const sMessage: string; sKeyMaterial: string): string;
{decode string}
function DeCryptString(const sMessage: string; sKeyMaterial: string): string;

function RandomKeyMaterial: string;
function StoreCryptString(const sMessage: string; sKeyMaterial: string): string;
function ReadCryptString(const sMessage: string; sKeyMaterial: string): string;


implementation

function RandomKeyMaterial: string;
var
  sTempKey: string;
  i: integer;
begin
  randomize;
  sTempKey:= '';
  for i:= 1 to (_KEYLength div 8) do
    sTempKey:= sTempKey+format('%.2X',[random(255)]);
  result:= sTempKey;
end;

function StoreCryptString(const sMessage: string; sKeyMaterial: string): string;
var
  sTempKey: string;
begin
  sTempKey:= RandomKeyMaterial;
{showmessage('Store:'+#10+
            'sTempKey="'+sTempKey+'"'+#10+
            'sMessage="'+sMessage+'"');}
  result:= EnCryptString(sTempKey,sKeyMaterial)+ EnCryptString(sMessage,sTempKey);
end;

function ReadCryptString(const sMessage: string; sKeyMaterial: string): string;
var
  sTempKey: string;
begin
  sTempKey:= DeCryptString(copy(sMessage,1,_KEYLength div 4),sKeyMaterial);
  result:= DeCryptString(copy(sMessage,1+(_KEYLength div 4),length(sMessage)),sTempKey);
{showmessage('Read:'+#10+
            'sTempKey="'+sTempKey+'"'+#10+
            'sMessage="'+result+'"');}
end;


function ExpandKey(sKey: string; iLength: integer): string;
var
  ikey: array [0..(_KEYLength div 8)-1] of byte;
  i,t: integer;
  sr: string;
begin
  sr:= sKey;
  FillChar(ikey,sizeof(ikey),0);
  try
    if (length(sr) mod 2)<> 0 then
      sr:= sr+ '0';
    t:= length(sr) div 2;
    if t> (iLength div 8) then
      t:= (iLength div 8);
    for i:= 0 to t-1 do
      ikey[i]:= strtoint('$'+sr[i*2+1]+sr[i*2+2]);
  except
  end;
  sr:= '';
  for i:= 0 to (iLength div 8)-1 do
    sr:= sr+IntToHex(ikey[i],2);
  result:= sr;
end;

function EnCryptString(const sMessage: string; sKeyMaterial: string): string;
var
  sres: string;
  blockLength,i: integer;
  keyInst: TkeyInstance;
  cipherInst: TcipherInstance;
begin
  keyInst.blockLen:= BITSPERBLOCK;
  sres:= ExpandKey(sKeyMaterial,_KEYLength);
  if makeKey(addr(keyInst), DIR_ENCRYPT, _KEYLength, pchar(sres))<> rTRUE then
    raise Exception.CreateFmt('Key error.',[-1]);
  cipherInst.blockLen:= BITSPERBLOCK;
  cipherInst.mode:= MODE_CBC;
  FillChar(cipherInst.IV,sizeof(cipherInst.IV),0);

  sres:= sMessage;
  blockLength:= length(sres)*8;
  if (blockLength mod BITSPERBLOCK)<> 0 then
    begin
      for i:= 1 to ((BITSPERBLOCK-(blockLength-(BITSPERBLOCK*(blockLength div BITSPERBLOCK)))) div 8) do
        sres:= sres+ ' ';
      blockLength:= length(sres)*8;
    end;

  if blocksEnCrypt(addr(cipherInst), addr(keyInst), addr(sres[1]), blockLength, addr(sres[1]))<> blockLength then
    raise Exception.CreateFmt('EnCrypt error.',[-2]);
  result:= sres;
end;

function DeCryptString(const sMessage: string; sKeyMaterial: string): string;
var
  sres: string;
  blockLength,i: integer;
  keyInst: TkeyInstance;
  cipherInst: TcipherInstance;
begin
  keyInst.blockLen:= BITSPERBLOCK;
  sres:= ExpandKey(sKeyMaterial,_KEYLength);
  if makeKey(addr(keyInst), DIR_DECRYPT, _KEYLength, pchar(sres))<> rTRUE then
    raise Exception.CreateFmt('Key error.',[-1]);
  cipherInst.blockLen:= BITSPERBLOCK;
  cipherInst.mode:= MODE_CBC;
  FillChar(cipherInst.IV,sizeof(cipherInst.IV),0);

  sres:= sMessage;
  blockLength:= length(sres)*8;
  if (blockLength= 0) or ((blockLength mod BITSPERBLOCK)<> 0) then
    raise Exception.CreateFmt('Wrong message length.',[-4]);

  if blocksDeCrypt(addr(cipherInst), addr(keyInst), addr(sres[1]), blockLength, addr(sres[1]))<> blockLength then
    raise Exception.CreateFmt('DeCrypt error.',[-3]);
  result:= trim(sres);
end;

end.

⌨️ 快捷键说明

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