【问题标题】:PHP encryption code converted to ColdFusionPHP加密代码转换为ColdFusion
【发布时间】:2011-08-14 01:35:54
【问题描述】:

我有一点 PHP,我想在 ColdFusion 中做类似的事情。

function & _encryptMessage( $message ) {

   $td = mcrypt_module_open( MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_CBC, '');
   mcrypt_generic_init( $td, $this->key, $this->iv );
   $encrypted_data = mcrypt_generic( $td, $message );
 mcrypt_generic_deinit($td);
 mcrypt_module_close($td);

   return base64_encode( $encrypted_data );
}

我觉得只是

encrypt(message,"","AES","Base64")

但我没有真正的方法可以确定,而且感觉不太对劲,所以我想知道是否有人足够优秀,可以为我指明正确的方向。

更新: 对于this answer 的信息Mister Dai,特别有帮助。

所以 MCRYPT_RIJNDAEL_256 实际上意味着block size not the encryption strength。加密强度仍然是 256,因为密钥和盐是在 PHP 中使用在 sha-256 散列的值生成的。

这是我现在的加密调用:

encrypt(arguments.messageXML,instance.key,"AES/CBC/PKCS5Padding","Base64",ivSalt)

不幸的是,由于 ivSalt 的长度为 32 字节(256 位),而 AES 只期望 16 字节的 iv 盐,所以这会爆炸。看着here,ColdFusion/Java 中用于 AES 的最大块大小似乎是 16 字节(128 位)。我似乎看不到如何获得 256 位块大小。任何帮助将不胜感激。

【问题讨论】:

  • 当您使用相同的消息运行这两个时,您会得到相同的结果吗?
  • 我同意戴夫的观点。但是有几件事让我感到震惊:1)您的 encrypt() key 丢失/空白 2)您没有通过 iv 和 3)加密 mode 需要与 php 使用的匹配跨度>
  • 啊...我刚刚想起一些关于 PHP 的事情。 this->key 类似于 ColdFusion 中的 this.key。所以我需要在 PHP 文件的其余部分中挖掘密钥和 IV 盐,这应该有助于我更理解这一点。
  • @Stephen Moretti - 您还需要更改mode。 IIRC CF 默认为 ECB,而 php 示例看起来正在使用 CBC
  • @Stephen Morretti - 如果 256 仅支持 Rijndael 而不是 AES,您可以尝试 Bouncy Castle 的 RijndaelEngine 实现 bouncycastle.org/specifications.html

标签: php encryption coldfusion aes rijndael


【解决方案1】:

http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7c52.html

你可以做一些简单的事情:

<cfset stringName = "variable 1: " & variable1 & " some more text" />
<cfset varName = HASH(stringName, "SHA") />

甚至这个:

<cfset varName = HASH("i want this string to be encrypted", "SHA") />

这样做通常是我为密码存储和其他敏感数据所做的。

希望链接和/或示例有所帮助, 品种

【讨论】:

  • 感谢您的帮助。我怀疑虽然哈希会加密字符串,但我需要能够解密结果。另外,除非我弄错了,否则 hash() 不支持 AES(RIJNDAEL 是 AES 对吗?)
  • 对。 Hash() 无法反转/解密,并且 AES/Rijndael 不是受支持的 hash 算法,只能使用 encrypt()。 help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/…
【解决方案2】:

在我回答我自己的问题之前,应该先表示感谢。感谢Dave Boyer (Mister Dai)Jason DeanJason Delmore 的帮助。

正如 Leigh 所建议的,我必须使用 Bouncy Castle、轻量级 API 和其中的 Rijndael 密码引擎。

我最终得到了一个创建 rijndael 密码的函数以及使用密钥和 ivsalt 加密和解密字符串的函数。

<cfcomponent displayname="Bounce Castle Encryption Component" hint="This provides bouncy castle encryption services" output="false">

<cffunction name="createRijndaelBlockCipher" access="private">
    <cfargument name="key" type="string" required="true" >
    <cfargument name="ivSalt" type="string" required="true" >
    <cfargument name="bEncrypt" type="boolean" required="false" default="1">
    <cfargument name="blocksize" type="numeric" required="false" default=256>
    <cfscript>
    // Create a block cipher for Rijndael
    var cryptEngine = createObject("java", "org.bouncycastle.crypto.engines.RijndaelEngine").init(arguments.blocksize);

    // Create a Block Cipher in CBC mode
    var blockCipher = createObject("java", "org.bouncycastle.crypto.modes.CBCBlockCipher").init(cryptEngine);

    // Create Padding - Zero Byte Padding is apparently PHP compatible.
    var zbPadding = CreateObject('java', 'org.bouncycastle.crypto.paddings.ZeroBytePadding').init();

    // Create a JCE Cipher from the Block Cipher
    var cipher = createObject("java", "org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher").init(blockCipher,zbPadding);

    // Create the key params for the cipher     
    var binkey = binarydecode(arguments.key,"hex");
    var keyParams = createObject("java", "org.bouncycastle.crypto.params.KeyParameter").init(BinKey);

    var binIVSalt = Binarydecode(ivSalt,"hex");
    var ivParams = createObject("java", "org.bouncycastle.crypto.params.ParametersWithIV").init(keyParams, binIVSalt);

    cipher.init(javaCast("boolean",arguments.bEncrypt),ivParams);

    return cipher;
    </cfscript>
</cffunction>

<cffunction name="doEncrypt" access="public" returntype="string">
    <cfargument name="message" type="string" required="true">
    <cfargument name="key" type="string" required="true">
    <cfargument name="ivSalt" type="string" required="true">

    <cfscript>
    var cipher = createRijndaelBlockCipher(key=arguments.key,ivSalt=arguments.ivSalt);
    var byteMessage = arguments.message.getBytes();
    var outArray = getByteArray(cipher.getOutputSize(arrayLen(byteMessage)));
    var bufferLength = cipher.processBytes(byteMessage, 0, arrayLen(byteMessage), outArray, 0);
    var cipherText = cipher.doFinal(outArray,bufferLength);

    return toBase64(outArray);
    </cfscript>
</cffunction>


<cffunction name="doDecrypt" access="public" returntype="string">
    <cfargument name="message" type="string" required="true">
    <cfargument name="key" type="string" required="true">
    <cfargument name="ivSalt" type="string" required="true">

    <cfscript>
    var cipher = createRijndaelBlockCipher(key=arguments.key,ivSalt=arguments.ivSalt,bEncrypt=false);
    var byteMessage = toBinary(arguments.message);
    var outArray = getByteArray(cipher.getOutputSize(arrayLen(byteMessage)));
    var bufferLength = cipher.processBytes(byteMessage, 0, arrayLen(byteMessage), outArray, 0);
    var originalText = cipher.doFinal(outArray,bufferLength);

    return createObject("java", "java.lang.String").init(outArray);
    </cfscript>
</cffunction>

<cfscript>
function getByteArray(someLength)
{
    byteClass = createObject("java", "java.lang.Byte").TYPE;
    return createObject("java","java.lang.reflect.Array").newInstance(byteClass, someLength);
}
</cfscript>

</cfcomponent>

doEncrypt 和 doDecrypt 函数是公开可见的,但不是创建 rijndael 密码的函数。加密和解密函数接受一个字符串,key 和 ivSalt 分别返回一个加密或解密的字符串。

createRijndaelBlockCipher 采用一个密钥 ivSalt,它是一个布尔值,用于说明密码是否将用于加密或解密以及块大小,尽管块大小默认为 256 位。该函数的注释相当好,所以它应该是有意义的。

底部的 UDF(特别感谢 Jason Delmore 提供的那个金块)确保 ColdFusion 正确地为解密创建了一个字节数组。其他一些创建字节数组的方法不起作用或最终导致解密结果不一致或抛出填充缓冲区损坏错误。

真的是这样。当标准的 AES 加密使用 128 位块并且 128 位密钥用于机密,192 位或更高位用于 TOP-SECRET 时,这需要付出太多的努力。 256 位块和 256 位密钥略高于顶部。仅仅因为你可以并不意味着你应该。

请记住,MCRYPT_RIJNDAEL_256 是块大小而不是加密级别。加密级别由您传递给 mcrypt_encrypt 的密钥强度设置,增加块大小不会增加加密强度。

【讨论】:

    猜你喜欢
    • 2015-04-03
    • 2013-04-17
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 2020-11-06
    相关资源
    最近更新 更多