【发布时间】:2011-12-10 17:24:00
【问题描述】:
我需要解密字符串格式 [0-9a-zA-Z+/] 的 base64 编码二进制文件。该字符串的一部分由 ivSalt 组成,即前 16 个字节或 128 位。剩下的就是数据;一切都使用 AES 加密,具有 128 个密钥和 128 个 CBC 块和 PKCS7Padding。
首先需要将字符串转换为二进制:
<cfset b64 = ToBinary(enc)/>
然后我们创建一个java字节缓冲区:
<cfset objByteBuffer = CreateObject(
"java",
"java.nio.ByteBuffer") />
然后我们为盐初始化一个缓冲区,为需要解密的数据初始化一个缓冲区。
<cfset objBufferA = objByteBuffer.Allocate(
JavaCast( "int", 16 )) />
<cfset objBufferB = objByteBuffer.Allocate(
JavaCast( "int", (Len(b64)-16) )) />
然后我们用我们的字节填充缓冲区。
<cfset objBufferA.Put(
b64,
JavaCast( "int", 0 ),
JavaCast( "int", 16 )) />
<cfset objBufferB.Put(
b64,
JavaCast( "int", 16 ),
JavaCast( "int", (Len(b64)-16) )) />
<cfset ivStringBin = objBufferA.Array()/>
<cfset dataStringBin = objBufferB.Array()/>
因为解密函数需要一个十六进制字符串,我们需要将其编码为十六进制。
<!--- create byteArray output stream --->
<cfset baos = createObject("java", "java.io.ByteArrayOutputStream")>
<!--- write the byteArray stored in the DB to the output stream --->
<cfset baos.write(ivStringBin)>
<!--- convert binary content to text string --->
<cfset ivString=BinaryEncode(baos.toByteArray(),"hex")/>
<!--- create byteArray output stream --->
<cfset baos2 = createObject("java", "java.io.ByteArrayOutputStream")>
<!--- write the byteArray stored in the DB to the output stream --->
<cfset baos2.write(dataStringBin)>
<!--- convert binary content to text string --->
<cfset dataString=BinaryEncode(baos2.toByteArray(),"hex")/>
应该是:
<cfset dataString=BinaryEncode(baos2.toByteArray(),"base64")/>
现在我不确定如何处理密钥,但它似乎需要采用十六进制字符串格式。
<cfset key = BinaryEncode(ToBinary("{16 chars, [0-9a-zA-Z+/]}")/>
应该是:
<cfset key = "{32 chars, [0-9A-Z]}"/>
ColdFusion 本身不支持带有 CBC 的 PKCS7Padding,我收到一个不受支持的提供程序错误。所以我去安装 BouncyCastle,我发现了一个很棒的 ColdFusion 示例,说明如何使用 PKCS5Padding 解密/重新加密 PHP 中的 ColdFusion 加密字符串>here。我将它添加到我的代码中,但我需要 PKCS7Padding,所以我更改了
var zbPadding = CreateObject('java', 'org.bouncycastle.crypto.paddings.ZeroBytePadding').init();
到
var zbPadding = CreateObject('java', 'org.bouncycastle.crypto.paddings.PKCS7Padding').init();
有了这一切,我得到了错误:
"Key length not 128/160/192/224/256 bits."
我会不断尝试,但我完全卡住了,我不知道我做错了什么。
编辑 1:
我搞定了!
- dataString 需要使用 base64 而不是十六进制。
- 使用 ColdFusion 转换为十六进制时,密钥是 24 个 [0-9A-F] 字符,代表 24x4=96 位,即 12 字节。它需要为 16 字节,因此 BinaryEncode(ToBinary()) 函数无法完成其工作。所以我使用了一个字符串到十六进制的工具来转换它,然后得到了 32 个字符。
编辑 2: 另外,为了安装 Bouncy Castle,我关注了 bouncy castle installe instructions 并从 java downloads 页面底部下载了 jce。
【问题讨论】:
-
您应该将其发布为答案并接受它。也许包括一个(缩写的)代码 sn-p 来帮助别人。
标签: coldfusion aes