Delphi AES加密(转)
- (**************************************************************)
- (* 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加密(转)的更多相关文章
- 透过 Delphi 使用二进位金钥做 AES 加密.
从 1994 年开始,笔者就开始接触加密与网路安全的世界,从鲁立忠老师的指导当中获益良多,后来在台湾的元智大学就读研究所的时候,也以此为研究主题. 在当时,电子商务是显学,Visa跟 Master C ...
- 关于CryptoJS中md5加密以及aes加密的随笔
最近项目中用到了各种加密,其中就包括从没有接触过得aes加密,因此从网上各种查,官方的一种说法: 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学 ...
- AES加密
package com.edu.hpu; import java.math.BigInteger; import java.security.MessageDigest; import java.se ...
- Android数据加密之Aes加密
前言: 项目中除了登陆,支付等接口采用rsa非对称加密,之外的采用aes对称加密,今天我们来认识一下aes加密. 其他几种加密方式: Android数据加密之Rsa加密 Android数据加密之Aes ...
- c#和js互通的AES加密解密
一.使用场景 在使用前后端分离的框架中常常会进行传输数据相互加密解密以确保数据的安全性,如web Api返回加密数据客户端或web端进行解密,或者客户端或web端进行加密提交数据服务端解密数据等等. ...
- AES加密解密通用版Object-C / C# / JAVA
1.无向量 128位 /// <summary> /// AES加密(无向量) /// </summary> /// <param name="plainByt ...
- nodejs与javascript中的aes加密
简介 1.aes加密简单来说,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用.高级加密标准已然成为对称密钥加 ...
- 非对称技术栈实现AES加密解密
非对称技术栈实现AES加密解密 正如前面的一篇文章所述,https协议的SSL层是实现在传输层之上,应用层之下,也就是说在应用层上看到的请求还是明码的,对于某些场景下要求这些http请求参数是非可读的 ...
- Java aes加密C#解密的取巧方法
摘要: 项目开发过程中遇到一个棘手的问题:A系统使用java开发,通过AES加密数据,B系统使用C#开发,需要从A系统获取数据,但在AES解密的时候遇到麻烦.Java的代码和C#的代码无法互通. Ja ...
随机推荐
- MyBatis无限输出日志
最近在项目中使用mybatis与spring集成,由于项目使用maven分模块打包,经常遇到mybatis mapper少配置子模块或者maven pom中忘记引用子模块导致的mybatis加载不到d ...
- AtCoder Regular Contest 095
AtCoder Regular Contest 095 C - Many Medians 题意: 给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数. \(n\le 200000\) 分析: ...
- jQuery和javaScript页面加载完成时触发的事件
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Pandas描述性统计
有很多方法用来集体计算DataFrame的描述性统计信息和其他相关操作. 其中大多数是sum(),mean()等聚合函数,但其中一些,如sumsum(),产生一个相同大小的对象. 一般来说,这些方法采 ...
- Java多线程 - 控制线程
join线程 在某个线程的执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到被join()方法加入的线程完成为止. join()方法有三种重载形式: join():等待被join的线程执 ...
- org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 语法分析器在此文档中遇到多个 "64,000" 实体扩展; 这是应用程序施加的限制
使用SAX解析XML文件.XML文件有1.5G,程序抛出了这个问题: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 语法 ...
- SpringCloud分布式开发理解
谈到SpringCloud最新接触到的可能就是那五大"神兽",之前最先接触分布式开发是通过dubbo的RPC远程过程调用,而dubbo给我得感觉就是:虽然所有的主机物理上分布了,但 ...
- easyui-textbox高为0
之前在项目中也遇到过,一段时间没遇到这种问题居然又忘记了,想着还是在博客中记录一下,方便自己记忆,也供大家参考. 大家是否也遇到过easyui-textbox高为0的情况呢 像这样: 用户名:< ...
- 0 与 “0" 与 '\0' 与 '0'相互之间的区别
1. '\0'和‘0’都是字符,对应的ASCII值分别是0和48. 2. 0表示一个数字.也可以表示ASCII值,对应字符'\0'. 3. “0”表示字符串,第一个字符是'0'.
- IOS-HTTP协议
网络由下往上分为 物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 通过初步的了解,我知道IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层, 三者从本质上来说没有可 ...