(**************************************************************)
(* Advanced Encryption Standard (AES) *)
(* Interface Unit v1.3 *)
(* *)
(* Copyright (c) 2002 Jorlen Young *)
(* *)
(* 说明: *)
(* 基于 ElASE.pas 单元封装 *)
(* *)
(* 这是一个 AES 加密算法的标准接口。 *)
(* 调用示例: *)
(* if not EncryptStream(src, key, TStream(Dest), keybit) then *)
(* showmessage('encrypt error'); *)
(* *)
(* if not DecryptStream(src, key, TStream(Dest), keybit) then *)
(* showmessage('encrypt error'); *)
(* *)
(* *** 一定要对Dest进行TStream(Dest) *** *)
(* ========================================================== *)
(* *)
(* 支持 128 / 192 / 256 位的密匙 *)
(* 默认情况下按照 128 位密匙操作 *)
(* *)
(**************************************************************) unit AES; interface {$IFDEF VER210}
{$WARN IMPLICIT_STRING_CAST OFF} //关闭警告
{$WARN IMPLICIT_STRING_CAST_LOSS OFF}
{$ENDIF}
uses
SysUtils, Classes, Math, ElAES; const
SDestStreamNotCreated = 'Dest stream not created.';
SEncryptStreamError = 'Encrypt stream error.';
SDecryptStreamError = 'Decrypt stream error.'; type
TKeyBit = (kb128, kb192, kb256); function StrToHex(Const str: AnsiString): AnsiString;
function HexToStr(const Str: AnsiString): AnsiString; function EncryptString(Value: AnsiString; Key: AnsiString;
KeyBit: TKeyBit = kb128): AnsiString;
function DecryptString(Value: AnsiString; Key: AnsiString;
KeyBit: TKeyBit = kb128): AnsiString; function EncryptStream(Src: TStream; Key: AnsiString;
var Dest: TStream; KeyBit: TKeyBit = kb128): Boolean;
function DecryptStream(Src: TStream; Key: AnsiString;
var Dest: TStream; KeyBit: TKeyBit = kb128): Boolean; procedure EncryptFile(SourceFile, DestFile: String;
Key: AnsiString; KeyBit: TKeyBit = kb128);
procedure DecryptFile(SourceFile, DestFile: String;
Key: AnsiString; KeyBit: TKeyBit = kb128); implementation function StrToHex(Const str: Ansistring): Ansistring;
asm
push ebx
push esi
push edi
test eax,eax
jz @@Exit
mov esi,edx //保存edx值,用来产生新字符串的地址
mov edi,eax //保存原字符串
mov edx,[eax-] //获得字符串长度
test edx,edx //检查长度
je @@Exit {Length(S) = 0}
mov ecx,edx //保存长度
Push ecx
shl edx,
mov eax,esi
{$IFDEF VER210}
movzx ecx, word ptr [edi-] {需要设置CodePage}
{$ENDIF}
call System.@LStrSetLength //设置新串长度
mov eax,esi //新字符串地址
Call UniqueString //产生一个唯一的新字符串,串位置在eax中
Pop ecx
@@SetHex:
xor edx,edx //清空edx
mov dl, [edi] //Str字符串字符
mov ebx,edx //保存当前的字符
shr edx, //右移4字节,得到高8位
mov dl,byte ptr[edx+@@HexChar] //转换成字符
mov [eax],dl //将字符串输入到新建串中存放
and ebx,$0F //获得低8位
mov dl,byte ptr[ebx+@@HexChar] //转换成字符
inc eax //移动一个字节,存放低位
mov [eax],dl
inc edi
inc eax
loop @@SetHex
@@Exit:
pop edi
pop esi
pop ebx
ret
@@HexChar: db '0123456789ABCDEF'
end; function HexToStr(const Str: AnsiString): AnsiString;
asm
push ebx
push edi
push esi
test eax,eax //为空串
jz @@Exit
mov edi,eax
mov esi,edx
mov edx,[eax-]
test edx,edx
je @@Exit
mov ecx,edx
push ecx
shr edx,
mov eax,esi //开始构造字符串
{$IFDEF VER210}
movzx ecx, word ptr [edi-] {需要设置CodePage}
{$ENDIF}
call System.@LStrSetLength //设置新串长度
mov eax,esi //新字符串地址
Call UniqueString //产生一个唯一的新字符串,串位置在eax中
Pop ecx
xor ebx,ebx
xor esi,esi
@@CharFromHex:
xor edx,edx
mov dl, [edi] //Str字符串字符
cmp dl, '' //查看是否在0到f之间的字符
JB @@Exit //小于0,退出
cmp dl,'' //小于=
ja @@DoChar//CompOkNum
sub dl,''
jmp @@DoConvert
@@DoChar:
//先转成大写字符
and dl,$DF
cmp dl,'F'
ja @@Exit //大于F退出
add dl,
sub dl,'A'
@@DoConvert: //转化
inc ebx
cmp ebx,
je @@Num1
xor esi,esi
shl edx,
mov esi,edx
jmp @@Num2
@@Num1:
add esi,edx
mov edx,esi
mov [eax],dl
xor ebx,ebx
inc eax
@@Num2:
dec ecx
inc edi
test ecx,ecx
jnz @@CharFromHex
@@Exit:
pop esi
pop edi
pop ebx
end; { -- 字符串加密函数 默认按照 128 位密匙加密 -- }
function EncryptString(Value: AnsiString; Key: AnsiString;
KeyBit: TKeyBit = kb128): AnsiString;
var
{$IFDEF VER210}
SS,DS: TMemoryStream;
{$ELSE}
SS, DS: TStringStream;
{$ENDIF}
Size: Int64;
AESKey128: TAESKey128;
AESKey192: TAESKey192;
AESKey256: TAESKey256;
st: AnsiString;
begin
Result := '';
{$IFDEF VER210}
ss := TMemoryStream.Create;
SS.WriteBuffer(PAnsiChar(Value)^,Length(Value));
DS := TMemoryStream.Create;
{$ELSE}
SS := TStringStream.Create(Value);
DS := TStringStream.Create('');
{$ENDIF}
try
Size := SS.Size;
DS.WriteBuffer(Size, SizeOf(Size));
{ -- 128 位密匙最大长度为 16 个字符 -- }
if KeyBit = kb128 then
begin
FillChar(AESKey128, SizeOf(AESKey128), );
Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
EncryptAESStreamECB(SS, , AESKey128, DS);
end;
{ -- 192 位密匙最大长度为 24 个字符 -- }
if KeyBit = kb192 then
begin
FillChar(AESKey192, SizeOf(AESKey192), );
Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
EncryptAESStreamECB(SS, , AESKey192, DS);
end;
{ -- 256 位密匙最大长度为 32 个字符 -- }
if KeyBit = kb256 then
begin
FillChar(AESKey256, SizeOf(AESKey256), );
Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
EncryptAESStreamECB(SS, , AESKey256, DS);
end;
{$IFDEF VER210}
SetLength(st,Ds.Size);
DS.Position := ;
DS.ReadBuffer(PAnsiChar(st)^,DS.Size);
Result := StrToHex(st);
{$ELSE}
Result := StrToHex(DS.DataString);
{$ENDIF}
finally
SS.Free;
DS.Free;
end;
end; { -- 字符串解密函数 默认按照 128 位密匙解密 -- }
function DecryptString(Value: AnsiString; Key: AnsiString;
KeyBit: TKeyBit = kb128): AnsiString;
var
SS, DS: TStringStream;
Size: Int64;
AESKey128: TAESKey128;
AESKey192: TAESKey192;
AESKey256: TAESKey256;
begin
Result := '';
SS := TStringStream.Create(HexToStr(Value));
DS := TStringStream.Create('');
try
Size := SS.Size;
SS.ReadBuffer(Size, SizeOf(Size));
{ -- 128 位密匙最大长度为 16 个字符 -- }
if KeyBit = kb128 then
begin
FillChar(AESKey128, SizeOf(AESKey128), );
Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
DecryptAESStreamECB(SS, SS.Size - SS.Position, AESKey128, DS);
end;
{ -- 192 位密匙最大长度为 24 个字符 -- }
if KeyBit = kb192 then
begin
FillChar(AESKey192, SizeOf(AESKey192), );
Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
DecryptAESStreamECB(SS, SS.Size - SS.Position, AESKey192, DS);
end;
{ -- 256 位密匙最大长度为 32 个字符 -- }
if KeyBit = kb256 then
begin
FillChar(AESKey256, SizeOf(AESKey256), );
Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
DecryptAESStreamECB(SS, SS.Size - SS.Position, AESKey256, DS);
end;
Result := DS.DataString;
finally
SS.Free;
DS.Free;
end;
end; { 流加密函数, default keybit: 128bit }
function EncryptStream(Src: TStream; Key: AnsiString;
var Dest: TStream; KeyBit: TKeyBit = kb128): Boolean;
var
Count: Int64;
AESKey128: TAESKey128;
AESKey192: TAESKey192;
AESKey256: TAESKey256;
begin
if Dest = nil then
begin
raise Exception.Create(SDestStreamNotCreated);
Result:= False;
Exit;
end; try
Src.Position:= ;
Count:= Src.Size;
Dest.Write(Count, SizeOf(Count));
{ -- 128 位密匙最大长度为 16 个字符 -- }
if KeyBit = kb128 then
begin
FillChar(AESKey128, SizeOf(AESKey128), );
Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
EncryptAESStreamECB(Src, , AESKey128, Dest);
end;
{ -- 192 位密匙最大长度为 24 个字符 -- }
if KeyBit = kb192 then
begin
FillChar(AESKey192, SizeOf(AESKey192), );
Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
EncryptAESStreamECB(Src, , AESKey192, Dest);
end;
{ -- 256 位密匙最大长度为 32 个字符 -- }
if KeyBit = kb256 then
begin
FillChar(AESKey256, SizeOf(AESKey256), );
Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
EncryptAESStreamECB(Src, , AESKey256, Dest);
end; Result := True;
except
raise Exception.Create(SEncryptStreamError);
Result:= False;
end;
end; { 流解密函数, default keybit: 128bit }
function DecryptStream(Src: TStream; Key: AnsiString;
var Dest: TStream; KeyBit: TKeyBit = kb128): Boolean;
var
Count, OutPos: Int64;
AESKey128: TAESKey128;
AESKey192: TAESKey192;
AESKey256: TAESKey256;
begin
if Dest = nil then
begin
raise Exception.Create(SDestStreamNotCreated);
Result:= False;
Exit;
end; try
Src.Position:= ;
OutPos:= Dest.Position;
Src.ReadBuffer(Count, SizeOf(Count));
{ -- 128 位密匙最大长度为 16 个字符 -- }
if KeyBit = kb128 then
begin
FillChar(AESKey128, SizeOf(AESKey128), );
Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
DecryptAESStreamECB(Src, Src.Size - Src.Position,
AESKey128, Dest);
end;
{ -- 192 位密匙最大长度为 24 个字符 -- }
if KeyBit = kb192 then
begin
FillChar(AESKey192, SizeOf(AESKey192), );
Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
DecryptAESStreamECB(Src, Src.Size - Src.Position,
AESKey192, Dest);
end;
{ -- 256 位密匙最大长度为 32 个字符 -- }
if KeyBit = kb256 then
begin
FillChar(AESKey256, SizeOf(AESKey256), );
Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
DecryptAESStreamECB(Src, Src.Size - Src.Position,
AESKey256, Dest);
end;
Dest.Size := OutPos + Count;
Dest.Position := OutPos; Result := True;
except
raise Exception.Create(SDecryptStreamError);
Result:= False;
end;
end; { -- 文件加密函数 默认按照 128 位密匙解密 -- }
procedure EncryptFile(SourceFile, DestFile: String;
Key: AnsiString; KeyBit: TKeyBit = kb128);
var
SFS, DFS: TFileStream;
Size: Int64;
AESKey128: TAESKey128;
AESKey192: TAESKey192;
AESKey256: TAESKey256;
begin
SFS := TFileStream.Create(SourceFile, fmOpenRead);
try
DFS := TFileStream.Create(DestFile, fmCreate);
try
Size := SFS.Size;
DFS.WriteBuffer(Size, SizeOf(Size));
{ -- 128 位密匙最大长度为 16 个字符 -- }
if KeyBit = kb128 then
begin
FillChar(AESKey128, SizeOf(AESKey128), );
Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
EncryptAESStreamECB(SFS, , AESKey128, DFS);
end;
{ -- 192 位密匙最大长度为 24 个字符 -- }
if KeyBit = kb192 then
begin
FillChar(AESKey192, SizeOf(AESKey192), );
Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
EncryptAESStreamECB(SFS, , AESKey192, DFS);
end;
{ -- 256 位密匙最大长度为 32 个字符 -- }
if KeyBit = kb256 then
begin
FillChar(AESKey256, SizeOf(AESKey256), );
Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
EncryptAESStreamECB(SFS, , AESKey256, DFS);
end;
finally
DFS.Free;
end;
finally
SFS.Free;
end;
end; { -- 文件解密函数 默认按照 128 位密匙解密 -- }
procedure DecryptFile(SourceFile, DestFile: String;
Key: AnsiString; KeyBit: TKeyBit = kb128);
var
SFS, DFS: TFileStream;
Size: Int64;
AESKey128: TAESKey128;
AESKey192: TAESKey192;
AESKey256: TAESKey256;
begin
SFS := TFileStream.Create(SourceFile, fmOpenRead);
try
SFS.ReadBuffer(Size, SizeOf(Size));
DFS := TFileStream.Create(DestFile, fmCreate);
try
{ -- 128 位密匙最大长度为 16 个字符 -- }
if KeyBit = kb128 then
begin
FillChar(AESKey128, SizeOf(AESKey128), );
Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
DecryptAESStreamECB(SFS, SFS.Size - SFS.Position, AESKey128, DFS);
end;
{ -- 192 位密匙最大长度为 24 个字符 -- }
if KeyBit = kb192 then
begin
FillChar(AESKey192, SizeOf(AESKey192), );
Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
DecryptAESStreamECB(SFS, SFS.Size - SFS.Position, AESKey192, DFS);
end;
{ -- 256 位密匙最大长度为 32 个字符 -- }
if KeyBit = kb256 then
begin
FillChar(AESKey256, SizeOf(AESKey256), );
Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
DecryptAESStreamECB(SFS, SFS.Size - SFS.Position, AESKey256, DFS);
end;
DFS.Size := Size;
finally
DFS.Free;
end;
finally
SFS.Free;
end;
end;
end.

Delphi AES加密(转)的更多相关文章

  1. 透过 Delphi 使用二进位金钥做 AES 加密.

    从 1994 年开始,笔者就开始接触加密与网路安全的世界,从鲁立忠老师的指导当中获益良多,后来在台湾的元智大学就读研究所的时候,也以此为研究主题. 在当时,电子商务是显学,Visa跟 Master C ...

  2. 关于CryptoJS中md5加密以及aes加密的随笔

    最近项目中用到了各种加密,其中就包括从没有接触过得aes加密,因此从网上各种查,官方的一种说法: 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学 ...

  3. AES加密

    package com.edu.hpu; import java.math.BigInteger; import java.security.MessageDigest; import java.se ...

  4. Android数据加密之Aes加密

    前言: 项目中除了登陆,支付等接口采用rsa非对称加密,之外的采用aes对称加密,今天我们来认识一下aes加密. 其他几种加密方式: Android数据加密之Rsa加密 Android数据加密之Aes ...

  5. c#和js互通的AES加密解密

    一.使用场景 在使用前后端分离的框架中常常会进行传输数据相互加密解密以确保数据的安全性,如web Api返回加密数据客户端或web端进行解密,或者客户端或web端进行加密提交数据服务端解密数据等等. ...

  6. AES加密解密通用版Object-C / C# / JAVA

    1.无向量 128位 /// <summary> /// AES加密(无向量) /// </summary> /// <param name="plainByt ...

  7. nodejs与javascript中的aes加密

    简介 1.aes加密简单来说,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用.高级加密标准已然成为对称密钥加 ...

  8. 非对称技术栈实现AES加密解密

    非对称技术栈实现AES加密解密 正如前面的一篇文章所述,https协议的SSL层是实现在传输层之上,应用层之下,也就是说在应用层上看到的请求还是明码的,对于某些场景下要求这些http请求参数是非可读的 ...

  9. Java aes加密C#解密的取巧方法

    摘要: 项目开发过程中遇到一个棘手的问题:A系统使用java开发,通过AES加密数据,B系统使用C#开发,需要从A系统获取数据,但在AES解密的时候遇到麻烦.Java的代码和C#的代码无法互通. Ja ...

随机推荐

  1. on绑定阻止冒泡失败

    使用zepto库,有如下dom <div id="J_parent"> <a href="#"> <span>点我有惊喜&l ...

  2. Pow,求x的y次幂

    算法分析:很显然用递归.但是直接用递归会造成栈溢出,时间复杂度是o(n).所以要用分治思想,时间复杂度是o(logN). public class Power { //栈溢出,时间复杂度是o(n) p ...

  3. RENOUNCEMENT

    I must not think of thee;and,tired yet syrong,I shun the thought that lurks in all delight--The thou ...

  4. Pandas窗口函数

    为了处理数字数据,Pandas提供了几个变体,如滚动,展开和指数移动窗口统计的权重. 其中包括总和,均值,中位数,方差,协方差,相关性等. 下来学习如何在DataFrame对象上应用上提及的每种方法. ...

  5. SSH学习(2)

    SVN概述 1 SVN体系结构 (1)svn服务器 -首先在svn服务器里面创建 仓库 (2)svn客户端 SVN服务器安装和使用 0 首先把项目add到svn服务器上 清除不小点击保存密码的设置 修 ...

  6. cmd 导出 SQLite数据库

  7. vue.js 1.0中用v-for遍历出的li中的@click事件在移动端无效

    在vue.js使用v-for遍历出的li中的@click事件在移动端无效,在网页端可以执行,代码如下 <template> <div class="rating-secti ...

  8. python匿名函数 与 内置函数

      一.匿名函数  1.定义: 匿名函数顾名思义就是指:是指一类无需定义标识符(函数名)的函数或子程序. 2.语法格式:lambda 参数:表达式 lambda语句中,开头先写关键字lambda,冒号 ...

  9. 神经网络训练时出现nan错误

    现在一直在用TensorFlow训练CNN和LSTM神经网络,但是训练期间遇到了好多坑,现就遇到的各种坑做一下总结 1.问题一;训练CNN的时候出现nan CNN是我最开始接触的网络,我的研究课题就是 ...

  10. chm下载地址收集

    Js_chm   http://jjidc.jb51.net:81/201007/books/W3C_javascript.rar jQuery_1.7_chm    http://jjidc.jb5 ...