PHP加密代码转换为ColdFusion

发布于 2024-11-04 04:10:19 字数 1304 浏览 1 评论 0 原文

我有一段 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")

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

更新 : 有关此答案的信息,作者:戴先生特别有帮助。

因此 MCRYPT_RIJNDAEL_256 实际上意味着块大小而不是加密强度。加密强度仍为 256,因为密钥和盐是使用在 sha-256 进行哈希处理的值在 PHP 中生成的。

这是我现在的加密调用:

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

不幸的是,这会失败,因为 ivSalt 是 32 字节(256 位)长度,AES 仅期望 16 字节 iv salt。查看此处,似乎 ColdFusion/Java 中的最大块大小AES 为 16 字节(128 位)。我似乎不明白如何获得 256 位块大小。任何帮助将不胜感激。

I have this bit of PHP that I'd like to do the equivalent of in 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 );
}

I think it is just

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

But I have no real way of knowing for sure and it doesn't feel quite right, so I wondered if someone out there would be good enough to point me in the right direction.

UPDATE :
For information this answer by Mister Dai, was particularly helpful.

So MCRYPT_RIJNDAEL_256 actually means block size not the encryption strength. The encryption strength is still 256 as the key and salt are generated in PHP using a value that is hashed at sha-256.

This is the encrypt call I have now :

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

Unfortunately this blows up because the ivSalt is 32 bytes (256bits) in length and AES is only expecting a 16 bytes iv salt. Looking here it would seem that the maximum block size in ColdFusion/Java for AES is 16bytes (128bit). I can't seem to see how I can get a 256bit block size. Any help would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迷荒 2024-11-11 04:10:19

在回答我自己的问题之前,我应该先表示感谢。感谢 Dave Boyer(戴先生)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 密码的函数不是公开可见的。加密和解密函数采用字符串、密钥和 ivSalt 分别返回加密或解密的字符串。

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

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

确实就是这样。当标准 AES 加密使用 128 位块且 128 位密钥用于机密级别、192 位或更高级别用于绝密级别时,这需要付出太多的努力。 256 位块和 256 位密钥有点过头了。仅仅因为你可以,并不意味着你应该这样做。

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

A couple of thanks should go out before I answer my own question. Thanks to Dave Boyer (Mister Dai), Jason Dean and Jason Delmore for their help.

As Leigh has suggested I had to make use of Bouncy Castle, the light weight API and the Rijndael cipher engine there in.

I ended up with a function to create an rijndael cipher and functions to encrypt and decrypt a string with a key and 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>

The doEncrypt and doDecrypt functions are publically visible, but not the function that creates the rijndael cipher. The encryption and decryption functions take a string, key and ivSalt returning an encrypted or decrypted string respectively.

The createRijndaelBlockCipher takes a key, ivSalt, a boolean to state whether the cipher will be used to encrypt or decrypt and the block size, although the block size is defaulted to 256 bits. The function is fairly well commented so it should make sense.

The UDF at the bottom (special thanks to Jason Delmore for that nugget) ensures that ColdFusion correctly creates a byte array for the decryption. Some other ways of creating byte arrays just don't work or end up with inconsistent results in decryption or throw pad buffer corrupt errors.

That's about it really. It took far too much effort, when the standard AES encryption uses 128bit blocks and 128 Bit Keys are for classified up to SECRET, 192-bit or higher for TOP-SECRET. 256bit blocks and 256bit keys are just a bit over the top. Just because you can doesn't mean you should.

Please do remember that MCRYPT_RIJNDAEL_256 is the block size and not the encryption level. The encryption level is set by the strength of key that you pass into mcrypt_encrypt and increasing the block size does not increase the encryption strength.

鼻尖触碰 2024-11-11 04:10:19

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") />

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

希望链接和/或示例有所帮助,
布雷兹

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

You could do something as simple as:

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

or even this:

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

Doing something like this is usually what i do for password storage and other sensitive data.

Hope that the link and/or examples help,
Brds

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文