6

外部システムから暗号化された文字列を受け取り、合意されたアルゴリズム/エンコーディングのセットアップに基づいて復号化する、Coldfusion9 で記述されたサイレント ログイン サービスがあります。これは、ASP/JAVA/PHP を実行しているシステムから何年もの間問題なく機能していましたが、現在、CryptoJS を使用して暗号化を実行するしかないクライアントがあり、私の人生では、なぜこれが機能しないのかわかりませんColdfusion で復号化します。

暗号化に関する私の知識は素晴らしいものではありませんが、CryptoJS で暗号化されたまったく同じ文字列/キーの暗号文は、暗号化を実行するたびに異なることに気付きましたが、Coldfusion/Java では常にまったく同じ暗号化された文字列を期待できます。これがエンコーディングに関連しているかどうかはわかりませんが、以前に他のシステムから暗号化された文字列を受け入れるこの問題に遭遇したことはないので、CryptoJS で暗号化する方法が間違っていることを願っています。

<cfoutput>

<!--- Set String and Key --->
<cfset theKey = toBase64("1234567812345678")>
<cfset string = "max.brenner@google.com.au">

<!--- 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>
4

1 に答える 1

13

次の 2 つの問題があるようです。

  1. CryptoJS は変数を として使用していませんkey。@ Miguel-F が述べたように、文字列を渡すと、「パスフレーズとして扱われ、実際のキーと IV を導出するために使用されます」 . どちらもランダムに生成されるため、暗号化された結果は変化し続けます。しかし、もっと重要なことは、CryptoJS がkeyCF コードのものとは完全に異なるものを使用していることを意味し、それが復号化() が失敗する理由です。(少なくともそれは理由の一部です...)

  2. 2 番目の問題は、アルゴリズム「AES」に加えて、モードパディング スキームの 2 つの暗号化設定が一致しなければならないことです。CryptoJS と ColdFusion はパディング スキームに同じデフォルトを使用しますが、「モード」は異なります。

3 つの設定すべてが両側で同じであることを確認する必要があります。とにかくECBよりも安全なので、CFでCBCモードを使用してみてください。注: IV 値を追加する必要があります。

CFコード:

<!--- this is the base64 encrypted value from CryptoJS ---> 
<cfset encrypted = "J2f66oiDpZkFlQu26BDKL6ZwgNwN7T3ixst4JtMyNIY=">
<cfset rawString = "max.brenner@google.com.au">
<cfset base64Key = "MTIzNDU2NzgxMjM0NTY3OA==">
<cfset base64IV = "EBESExQVFhcYGRobHB0eHw==">

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

CryptoJS: (元の例を調整)

<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>


編集:

そうは言っても、クライアントが「CryptoJSを使用して暗号化を実行するしかない」とはどういう意味ですか? サーバー側の暗号化を使用できないのはなぜですか? 私は暗号化の専門家ではありませんが、javascript で暗号化を行い、クライアントでキーを公開することは、そもそも非常に安全とは思えません...

于 2013-05-17T17:57:31.743 に答える