导航:
论坛 -> DELPHI技术
斑竹:liumazi,sephil
作者:
2019/1/11 13:59:53
标题:
aes-256-cbc 在Delphi的实现,我代码参考cnpack里,貌似算法有问题
浏览:7015
加入我的收藏
楼主:
nodeJS代码: //加密 function encode(cryptkey, iv, cleardata) { var encipher = crypto.createCipheriv('aes-256-cbc', cryptkey, iv), encoded = encipher.update(cleardata, 'utf8', 'base64'); encoded += encipher.final( 'base64' ); return encoded; } //解密 function decode(cryptkey, iv, secretdata) { var decipher = crypto.createDecipheriv('aes-256-cbc', cryptkey, iv), decoded = decipher.update(secretdata, 'base64', 'utf8'); decoded += decipher.final( 'utf8' ); return decoded; } 要转成Delphi,加密(我使用cnpack的CnAes单元函数): { -- 字符串加密函数CBC -- } function EnCrypt_CBC(Value: AnsiString; Key, Iv { 偏移量 } : AnsiString): string; var SSrc, SS64, Out_64, Out_Ms: TStringStream; // Ms: TMemoryStream; AESKey256: TAESKey256; AESVI: TAESBuffer; begin Value := Trim(Value); SSrc := TStringStream.Create(Value, TEncoding.UTF8); // 将字符转UTF8格式,并存储 SS64 := TStringStream.Create('', TEncoding.UTF8); Out_64 := TStringStream.Create('', TEncoding.UTF8); Out_Ms := TStringStream.Create('', TEncoding.UTF8); try EncodeStream(SSrc, SS64); // 将字符串UTF8转为Base64 Move(Iv[1], AESVI[0], Length(Iv)); FillChar(AESKey256, SizeOf(AESKey256), 0); Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); EncryptAESStreamCBC(SS64, 0, AESKey256, AESVI, Out_Ms); // AES-256-CBC Out_Ms.Position := 0; EncodeStream(Out_Ms, Out_64); // 将密文转Base64 Result := Out_Ms.DataString; // 返回base64 finally Out_Ms.Free; SS64.Free; SSrc.Free; Out_64.Free; end; end; 是不是流程搞错了? 我的出来的结果和那个Nodejs的不一样。请教一下,谢谢
----------------------------------------------
-
作者:
2019/1/11 14:04:20
1楼:
你吧 node.js 的加密结果发出来,我试试。如果我能解密。 就告诉你从哪里下代码。
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/1/11 14:44:51
2楼:
好的大侠。 明文:method=roomCtrl&hid=1&roomno=8101&time=1533100989 密码:LSD832149 密码要做SHA256后小写 偏移量:1234567890000000 最后的密文是:A019F4e7zKhOSaeo11CjaYrinq391kiiCMOHexdItZH9gn6GlEjHJ0WqmZmulYgzRGmdb1rUyy+SL7DjML4fRw== 谢谢:)
----------------------------------------------
-
作者:
2019/1/11 14:46:11
3楼:
代码是一家做智慧房控的企业的。我们用Delphi做接口:)
----------------------------------------------
-
作者:
2019/1/11 14:48:52
4楼:
这是他们nodejs的测试代码: var cryptkey = crypto.createHash('sha256').update('LSD832149').digest(), iv = '1234567890000000', buf = "method=roomCtrl&hid=1&roomno=8101&time=1533100989", enc = encode( cryptkey, iv, buf ); var dec = decode(cryptkey, iv, enc); console.log("Encoded length: ", enc); console.log("Decoded all: " + dec);
----------------------------------------------
-
作者:
2019/1/11 15:11:20
5楼:
密码:LSD832149 密码要做SHA256后小写 我懒得写代码 请给出 SHA256 的结果。
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/1/11 15:36:25
6楼:
feed2eee848813fe580178c7ee130d6f21c0378fc36d6fab44644146c5be87f1 非常谢谢:)
----------------------------------------------
-
作者:
2019/1/11 15:55:53
7楼:
你 把 cryptkey 的结果 显示出来,截图。
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/1/11 16:39:36
8楼:
cryptkey 就是这个呢: feed2eee848813fe580178c7ee130d6f21c0378fc36d6fab44644146c5be87f1 这个是准确的,厂家确认过。
----------------------------------------------
-
作者:
2019/1/11 17:18:57
9楼:
https://www.jianshu.com/p/ca5859da2891 这篇文档。他的加密结果,我能解开。 我加密的结果,是随机的。每次不一样。
此帖子包含附件: 大小: 19.4K
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/1/11 17:36:43
10楼:
这样啊,你能否帮我试一下这一串明文: method=roomCtrl&hid=1&roomno=8101&time=1533100989 看看你加密一下,我调用他们的,看看是否能解?
----------------------------------------------
-
作者:
2019/1/11 17:41:10
11楼:
他们这个是这样的: http://test.lierdalux.cn/doHotel?cdata=A019F4e7zKhOSaeo11CjaYrinq391kiiCMOHexdItZH9gn6GlEjHJ0WqmZmulYgzRGmdb1rUyy+SL7DjML4fRw==&hid=1 中间那串cdata就是加密串,正常的返回: { "success": true, "msg": "认证成功", "data": { "url": "http://test.lierdalux.cn/inner#yc?nat=9d072e40a1f18aae1e1d0af41f48c0dd&link=lierda&efftime=600" } } 不正常,就是解密失败了:) 麻烦你了!
----------------------------------------------
-
作者:
2019/1/11 17:44:44
12楼:
http://www.01happy.com/nodejs-aes-128-cbc/ 这篇文章的最后的结果。 我也可以解密。
此帖子包含附件: 大小: 22.0K
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/1/11 17:46:40
13楼:
方便把代码给我,或者贴出来,我来试试吗? 万分感谢
----------------------------------------------
-
作者:
2019/1/11 17:49:13
14楼:
呃解密不了对吧? 我贴出那个加密后的密文后,他们说,密文字符串里应该不会有 / 斜杠。
----------------------------------------------
-
作者:
2019/1/11 17:50:13
15楼:
base64 允许有 /
----------------------------------------------
(C)(P)Flying Wang
作者:
glwang (glwang)
★☆☆☆☆
-
盒子活跃会员
2019/1/12 9:31:34
16楼:
楼主怎么没有回音啦?
----------------------------------------------
作者:
2019/1/12 9:46:45
17楼:
嗯,目前还是搞不定,尝试了好几个方法,跟nodejs的密文不对。
----------------------------------------------
-
作者:
2019/1/12 9:49:21
18楼:
算法本身的代码,我也看不懂,大致都是搬来的算法,然后写外围函数适配和调用。我这里也说了,目前我使用cnpack的aes算法单元。 只是写了个外围函数去按照厂家提供的nodejs代码加密要求进行编码。 尝试了大半天了,貌似目前没有什么解决方案
----------------------------------------------
-
作者:
2019/1/12 20:42:59
19楼:
是否是怀疑CnPack里的CnAES单元里的CBC算法有问题?我们查一下。
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2019/1/13 9:42:40
20楼:
楼上高手,你没看到 9楼 和 12楼 的内容吗? 都是网上的 node.js 的加密结果,我们 DLEPHI 解密完全正常。 node.js 加密结果也带有 / 。 楼主说不能有 / ,明显就是骗人的。 对于骗子认为的 问题,根本就没必要认为是问题。 我的代码,明明就是 CnVCL 的内容 从 AnsiString 改成了 TBytes 而已。 算法并没有任何变化。足以证明 CnVCL 的算法没有任何错误。 所以,检查也是浪费您的时间。
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/1/13 16:35:04
21楼:
Base64我印象中有两个规范版本,一个是基本版可能含有/,另一个是为了互联网URL传播方便去掉了/以及+的,可能和楼主的问题有点关系。
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2019/1/14 9:42:56
22楼:
to wang_80919:还是谢谢你的解答。不过你那样讲话,现实中估计吃过不少亏吧? to cnpack:确实是厂家说我的base64里不应该包含/符号,我没有理解像你那样深刻,那这样,我得再寻找不带/和+的base64算法? 我个人觉得应该cnpack还是比较靠谱的,我一直用。里面的des加密协助我解决了大问题。感谢提供这么好用的组件和代码给大家。
----------------------------------------------
-
作者:
2019/1/14 10:36:17
23楼:
一个分组加密算法在实际中使用,除了算法本身外,还有分组时的组间运算关系、不满足分组长度时的填充规范、密文如何转变成可读明文等细节。 算法本身,CnPack里的CnAES应该目前暂时没什么错误。 分组的组间关系,CnAES实现了ECB与CBC两种。 不满足分组长度时的填充规范,常用的有PKCS#1、PKCS#7等,CnAES未做填充处理,这里也可能是楼主的问题点。 密文变成明文:一般都用Base64,但要考虑是否是适配过URL的不带/与+的算法版本。
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2019/1/14 10:58:52
24楼:
楼主,你解决不了问题,我会吃亏吗? 不过 我的确 水平低,我根本就找不到 不采用 / 的 Base64 算法。 网上只有 + 变空格这个问题。 解决办法,就是 URLEncoding 。
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/1/14 11:18:51
25楼:
谢谢 cnpack (CnPack)。我也相信没问题,可能在于理解或者其他方面的兼容性,根据你的提示,我们会再认真尝试。多谢
----------------------------------------------
-
作者:
2019/1/14 11:46:30
26楼:
https://blog.csdn.net/janronehoo/article/details/46774885 https://en.wikipedia.org/wiki/Base64 看Encoding
----------------------------------------------
[alias] co = clone --recurse-submodules up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/ >http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
作者:
2019/1/23 9:06:14
27楼:
//HexToStr,StrToHex在CnAES里面有实现,需要在声明部分声明一下 uses CnAES,IdHashSHA, IdSSLOpenSSLHeaders, CnBase64; function EnCrypt_CBC256(Value: AnsiString; Key, Iv : AnsiString): string; var ctx:PEVP_CIPHER_CTX; cipher:PEVP_CIPHER; sKey:array[0..31] of Ansichar; ciphertext:array[0..63] of Ansichar; i,k,ciphertext_len,ilen,iplanlen:Integer; SHA256 : TIdHashSHA256; SS:TStringStream; begin SHA256 := TIdHashSHA256.Create; Key := LowerCase(SHA256.HashStringAsHex(Key)); SHA256.Free; i:=1; k:=0; while i<length(Key) do begin sKey[k]:=Ansichar(strtoint('$'+copy(Key,i,2))); inc(i,2); inc(k); end; ctx:=EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(ctx,EVP_aes_256_cbc(),nil,sKey,PAnsichar(IV)); EVP_EncryptUpdate(ctx,ciphertext,@ilen,PAnsichar(Value),length(Value)); ciphertext_len:=ilen; EVP_EncryptFinal_ex(ctx,ciphertext+ilen,@ilen); inc(ciphertext_len,ilen); SS:=TStringStream.Create; SS.Write(ciphertext,ciphertext_len); SS.Position:=0; Base64Encode(HexToStr(StrToHex(PAnsiChar(SS.Memory),SS.Size)),result); EVP_CIPHER_CTX_free(ctx); end; //调用 //edit1.Text:='method=roomCtrl&hid=1&roomno=8101&time=1533100989'; //edit2.Text:='LSD832149'; //edit3.Text:='1234567890000000'; edRs.Text:=EnCrypt_CBC256(edit1.Text,edit2.Text,edit3.Text); initialization IdSSLOpenSSLHeaders.Load();
----------------------------------------------
-
作者:
2019/1/23 9:41:02
28楼:
uses FlyUtils.CnXXX.Common, FlyUtils.AES, System.Hash, System.NetEncoding; function EnCrypt_CBC256(const Value: AnsiString; Key, Iv : string): string; var KeyBytes, IvBytes, OutBytes: TBytes; begin KeyBytes := THashSHA2.GetHashBytes(Key, THashSHA2.TSHA2Version.SHA256); IvBytes := TEncoding.ANSI.GetBytes(Iv); OutBytes := AESEncryptStr_BytesKey(Value, KeyBytes, IvBytes, TEncoding.UTF8, TKeyBit.kb256, TPaddingMode.pmPKCS5or7Padding, True); Result := TNetEncoding.Base64.EncodeBytesToString(OutBytes); end; procedure TForm1.Button1Click(Sender: TObject); begin Edit4.Text := EnCrypt_CBC256(Edit1.Text, Edit2.Text, Edit3.Text); end; 好奇怪,居然完美的避开了 / http://test.lierdalux.cn/doHotel?cdata=A019F4e7zKhOSaeo11CjaYrinq391kiiCMOHexdItZHlgqMEA1Xi0xamxhyuCOQtfzal2r1PyaUi rjZjVA4ajA==&hid=1 我之所以加密被认为错误 是 因为,我采用了 随机填充,上面的代码,是不随机的,就可以了。
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/1/24 10:58:49
29楼:
to wangdonghai (wdh),太感谢了。 这个加密的,我比较菜鸟,能否劳烦,把解密的也帮忙一下?万分感谢 谢谢wang_80919 (Flying Wang)
----------------------------------------------
-
作者:
2019/1/24 11:05:28
30楼:
FlyUtils.AES 加密解密 代码调用都差不多。 function DeCrypt_CBC256(const Value: AnsiString; Key, Iv : string): string; var KeyBytes, IvBytes, InBytes: TBytes; begin KeyBytes := THashSHA2.GetHashBytes(Key, THashSHA2.TSHA2Version.SHA256); IvBytes := TEncoding.ANSI.GetBytes(Iv); InBytes := TNetEncoding.Base64.DecodeStringToBytes(Value); Result := AESDecryptStr_BytesKey(IvBytes, KeyBytes, IvBytes, TEncoding.UTF8, TKeyBit.kb256, TPaddingMode.pmPKCS5or7Padding, True); end;
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/1/24 16:43:38
31楼:
delphi10.3 indy里面的IdSSLOpenSSLHeaders里面的EVP_DecryptUpdate和EVP_DecryptFinal_ex声明有误,需要重新自己声明一下,openssl AES加密解密参考了 https://blog.csdn.net/yasi_xi/article/details/13997337 uses CnAES,IdHashSHA,IdSSLOpenSSLHeaders, CnBase64, IdCTypes, IdGlobal; var function MyEVP_DecryptUpdate(ctx : PEVP_CIPHER_CTX; _out : PIdAnsiChar; outl : PIdC_INT; _in : PIdAnsiChar; inl : TIdC_INT) : TIdC_INT ; cdecl;external 'libeay32.dll' name 'EVP_DecryptUpdate'; function MyEVP_DecryptFinal_ex(ctx : PEVP_CIPHER_CTX; outm: PIdAnsiChar; outl : PIdC_INT) : TIdC_INT; cdecl;external 'libeay32.dll' name 'EVP_DecryptFinal_ex'; function DecCrypt_CBC256(Value: AnsiString; Key, Iv : AnsiString): string; var ctx:PEVP_CIPHER_CTX; cipher:PEVP_CIPHER; sKey:array[0..31] of Ansichar; ciphertext:array[0..63] of Ansichar; i,k,ciphertext_len,ilen,iplanlen:Integer; SHA256 : TIdHashSHA256; SS:TStringStream; begin SHA256 := TIdHashSHA256.Create; Key := LowerCase(SHA256.HashStringAsHex(Key)); SHA256.Free; i:=1; k:=0; while i<length(Key) do begin sKey[k]:=Ansichar(strtoint('$'+copy(Key,i,2))); inc(i,2); inc(k); end; SS:=TStringStream.Create; Base64Decode(Value,SS); Value:=StrToHex(PAnsiChar(SS.Memory),SS.Size); Value:=HexToStr(Value); SS.Free; ctx:=EVP_CIPHER_CTX_new(); EVP_DecryptInit_ex(ctx,EVP_aes_256_cbc(),nil,sKey,PAnsichar(IV)); fillchar(ciphertext,sizeof(ciphertext),#0); ilen:=sizeof(ciphertext); MyEVP_DecryptUpdate(ctx,ciphertext,@ilen,PAnsichar(Value),length(Value)); ciphertext_len:=ilen; MyEVP_DecryptFinal_ex(ctx,ciphertext+ilen,@ilen); inc(ciphertext_len,ilen); EVP_CIPHER_CTX_free(ctx); ciphertext[ciphertext_len]:=#0; result:=ciphertext; end; initialization IdSSLOpenSSLHeaders.Load();
----------------------------------------------
-
作者:
2019/1/25 11:30:51
32楼:
感谢两位高手的鼎力相助。Delphi界有如此热心大侠,真是福气。多谢
----------------------------------------------
-