PHP加密代码转换为ColdFusion

PHP encryption code converted to ColdFusion

我有一部分PHP想在ColdFusion中完成。

1
2
3
4
5
6
7
8
9
10
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 );
}

我认为这只是

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

但是我没有真正确定的确切方法,而且感觉不太正确,所以我想知道外面有人是否足以将我指向正确的方向。

更新:
有关信息,戴先生的答案特别有用。

因此MCRYPT_RIJNDAEL_256实际上表示块大小,而不是加密强度。加密强度仍然是256,因为密钥和salt是使用在sha-256处散列的值在PHP中生成的。

这是我现在拥有的加密呼叫:

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

不幸的是,由于ivSalt的长度为32字节(256位),而AES仅期望16字节的ivsalt,因此此操作会失败。从这里看,似乎ColdFusion / Java中用于AES的最大块大小为16字节(128位)。我似乎看不到如何获得256位块大小。任何帮助将不胜感激。


在我回答自己的问题之前,应该先感谢几位。感谢Dave Boyer(戴先生),Jason Dean和Jason Delmore的帮助。

正如Leigh所建议的那样,我不得不使用其中的Bouncy Castle,轻量级API和Rijndael密码引擎。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<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位密钥分类为SECRET,对于TOP-SECRET分类为192位或更高时,这花费了太多的精力。 256位块和256位密钥仅在顶部之上。仅仅因为您可以,并不意味着您应该这样做。

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


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

您可以做以下简单的事情:

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

甚至是这个:

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

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

希望链接和/或示例有帮助,
Brds