Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
785 views
in Technique[技术] by (71.8m points)

javascript - AES Encrypt in CryptoJS and decrypt in Coldfusion

We've got a Silent Login service written in Coldfusion9 that accepts encrypted strings from external systems and then decrypts based on an agreed Algorithm/Encoding setup. This has worked without issue for years now from systems running ASP/JAVA/PHP, but we now have a client who has no choice but to use CryptoJS to perform the encryption and for the life of me I cannot work out why this won't decrypt in Coldfusion.

My knowledge of encryption isn't brilliant but the thing I am noticing is the CryptoJS encrypted ciphertext for the exact same string/key differs every time i perform the encryption whereas in Coldfusion/Java i can always expect the exact same encrypted string. I'm not sure if this is encoding related or not but i've never run into this issue accepting encrypted strings from any other system before, so I am hoping it's the way I am encrypting in CryptoJS that is incorrect.

<cfoutput>

<!--- Set String and Key --->
<cfset theKey = toBase64("1234567812345678")>
<cfset string = "[email protected]">

<!--- CryptoJS AES Libraries --->
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js"></script>

<script>

// Encrypt String using CryptoJS AES
var encrypted = CryptoJS.AES.encrypt("#string#", "#theKey#");
console.log(encrypted.toString());

// Decrypt String using CryptoJS AES 
var decrypted = CryptoJS.AES.decrypt(encrypted, "#theKey#");
console.log(decrypted.toString(CryptoJS.enc.Utf8));

</script>

<!--- Coldfusion Decrypt String / FAILS --->
Decrypted: #decrypt(encryptedEmail, "#theKey#", "AES", "BASE64")#

</cfoutput>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There seem to be two issues:

  1. CryptoJS is not using your variable as the key. As @Miguel-F mentioned, when you pass in a string, "it's treated as a passphrase and used to derive [the] actual key and IV". Both are randomly generated, which is why your encrypted result keeps changing. But more importantly, this means that CryptoJS is using a completely different key than the one in your CF code and that is why decrypt() fails. (At least it is part of the reason ...)

  2. The second problem is that in addition to the algorithm "AES", there are two other encryption settings which must match: mode and padding scheme. While CryptoJS and ColdFusion use the same defaults for padding scheme, the "modes" are different:

You need to ensure all three settings are the same on both sides. Try using CBC mode in CF, since it is more secure than ECB anyway. Note: It requires adding an IV value.

CF Code:

<!--- this is the base64 encrypted value from CryptoJS ---> 
<cfset encrypted = "J2f66oiDpZkFlQu26BDKL6ZwgNwN7T3ixst4JtMyNIY=">
<cfset rawString = "[email protected]">
<cfset base64Key = "MTIzNDU2NzgxMjM0NTY3OA==">
<cfset base64IV = "EBESExQVFhcYGRobHB0eHw==">

<cfset ivBytes = binaryDecode(base64IV, "base64")>
<cfoutput>
    #decrypt(encrypted, base64Key, "AES/CBC/PKCS5Padding", "base64", ivBytes)#
</cfoutput>

CryptoJS: (Adjusted Original Example)

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js"></script>
<script>
    var text = "#rawString#";
    var key = CryptoJS.enc.Base64.parse("#base64Key#");
    var iv  = CryptoJS.enc.Base64.parse("#base64IV#");

    var encrypted = CryptoJS.AES.encrypt(text, key, {iv: iv});
    console.log(encrypted.toString());

    var decrypted = CryptoJS.AES.decrypt(encrypted, key, {iv: iv});
    console.log(decrypted.toString(CryptoJS.enc.Utf8));
</script>


Edit:

All that said, what do you mean by the client "has no choice but to use CryptoJS to perform the encryption"? Why cannot they use server side encryption? I am not an encryption expert, but doing encryption in javascript, and exposing the key on the client, does not sound wildly secure to begin with ...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...