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

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

问题描述

我有这个位的PHP,我想做相当于在ColdFusion。

 功能& _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)

但我没有真正的方式知道肯定,它不觉得很对,所以我想知道有人在那里会好到足以指出我的正确方向。



UPDATE:
有关信息 Mister Dai 的回答特别有用。



因此,MCRYPT_RIJNDAEL_256实际上意味着块大小而不是加密强度< a>。加密强度仍然是256,因为密钥和盐是使用在sha-256哈希的值生成的。



这是我现在的加密调用:



encrypt(arguments.messageXML,instance.key,AES / CBC / PKCS5Padding,Base64,ivSalt)这里,似乎ColdFusion / Java中的最大块大小AES是16字节(128位)。我似乎不能看到我如何可以获得一个256位的块大小。任何帮助将非常感激。

解决方案

在回答我自己的问题之前,感谢 Dave Boyer(Mister Dai) Jason Dean Jason Delmore 寻求帮助。



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



我最后创建了一个函数来创建一个rijndael密码和函数,用一个键和ivsalt加密和解密一个字符串。

  < cfcomponent displayname =Bounce Castle Encryption Componenthint =This provides bouncy castle encryption servicesoutput =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);

//创建Padding - Zero Byte Padding显然是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);

返回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);

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

< cfscript>
function getByteArray(someLength)
{
byteClass = createObject(java,java.lang.Byte)。
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位密钥分类为SECRET,192位或更高的TOP-SECRET。 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天全站免登陆