PHP加密代码转换为ColdFusion [英] PHP encryption code converted to ColdFusion

查看:99
本文介绍了PHP加密代码转换为ColdFusion的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这么一点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);

返回base64_encode($ encrypted_data);
}

我认为这只是

  encrypt(message,,AES,Base64)

但我没有真正的知道的方式,它的感觉不是很正确,所以我想知道有没有人会对我指出正确的方向。



更新:
有关信息这个答案通过 Dister先生,特别有帮助。



所以MCRYPT_RIJNDAEL_256实际上意味着块大小不是加密强度。加密强度仍然是256,因为关键和盐在PHP中使用在sha-256上散列的值生成。



这是我现在的加密调用:



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



不幸的是,由于ivSalt的长度为32字节(256位),AES只能预期16字节的静盐,看看 here ,看来ColdFusion / Java中的最大块大小AES为16字节(128位)。我似乎看不到我能得到一个256位的块大小。任何帮助将不胜感激。

解决方案

几个感谢应该在我回答我自己的问题之前出去。感谢 Dave Boyer(Dister先生) Jason Dean Jason Delmore 寻求帮助。

由于Leigh建议我不得不使用Bouncy Castle,轻量级API和Rijndael密码引擎。



我最终用一个函数来创建一个rijndael密码,并使用key和ivsalt来加密和解密一个字符串。

  < cfcomponent displayname =Bounce Castle Encryption Componenthint =这提供了bouncy城​​堡加密服务output =false> 

< cffunction name =createRijndaelBlockCipheraccess =private>
< cfargument name =keytype =stringrequired =true>
< cfargument name =ivSalttype =stringrequired =true>
< cfargument name =bEncrypttype =booleanrequired =falsedefault =1>
< cfargument name =blocksizetype =numericrequired =falsedefault = 256>
< cfscript>
//为Rijndael
创建块密码var cryptEngine = createObject(java,org.bouncycastle.crypto.engines.RijndaelEngine)。init(arguments.blocksize);

//在CBC模式下创建块密码
var blockCipher = createObject(java,org.bouncycastle.crypto.modes.CBCBlockCipher)。init(cryptEngine);

//创建填充 - 零字节填充显然是PHP兼容的。
var zbPadding = CreateObject('java','org.bouncycastle.crypto.paddings.ZeroBytePadding')。init();

//从块密码创建一个JCE密码
var cipher = createObject(java,org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher)init(blockCipher,zbPadding) ;

//为密码创建密钥参数
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 =doEncryptaccess =publicreturntype =string>
< cfargument name =messagetype =stringrequired =true>
< cfargument name =keytype =stringrequired =true>
< cfargument name =ivSalttype =stringrequired =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 =doDecryptaccess =publicreturntype =string>
< cfargument name =messagetype =stringrequired =true>
< cfargument name =keytype =stringrequired =true>
< cfargument name =ivSalttype =stringrequired =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);

返回createObject(java,java.lang.String)。init(outArray);
< / cfscript>
< / cffunction>

< cfscript>
函数getByteArray(someLength)
{
byteClass = createObject(java,java.lang.Byte)。TYPE;
返回createObject(java,java.lang.reflect.Array)。newInstance(byteClass,someLength);
}
< / cfscript>

< / cfcomponent>

doEncrypt和doDecrypt函数是公开可见的,但不是创建rijndael密码的函数。加密和解密函数采用字符串,键和ivSalt分别返回加密或解密的字符串。



createRijndaelBlockCipher需要一个键,ivSalt,一个布尔值来表示密码将用于加密或解密和块大小,尽管块大小默认为256位。该功能相当好的评论,所以应该是有道理的。



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



这是真的。当采用128位块标准的AES加密和128位密钥分类为SECRET,TOP-SECRET为192位或更高版本时,花费了太多的精力。 256位块和256位密钥仅仅位于顶部。只因为你可以不意味着你应该。



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


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.

解决方案

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.

这篇关于PHP加密代码转换为ColdFusion的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆