AES Cryptage dans CryptoJS et Décryptage dans Coldfusion

Nous avons un service de connexion silencieuse écrit dans Coldfusion9 qui accepte des chaînes cryptées à partir de systèmes externes, puis décrypte en fonction d'une configuration d'algorithme / codage approuvée. Cela a fonctionné sans problème depuis des années à partir de systèmes exécutant ASP / JAVA / PHP, mais nous avons maintenant un client qui n'a d'autre choix que d'utiliser CryptoJS pour effectuer le cryptage et pour la vie de moi, je ne peux pas comprendre pourquoi ce ne sera pas Décrypter dans Coldfusion.

Ma connaissance du cryptage n'est pas géniale, mais ce que je remarque, c'est que le CryptoJS chiffré le texte chiffré pour exactement la même chaîne / clé diffère chaque fois que je réalise le cryptage alors que dans Coldfusion / Java, je peux toujours m'attendre à la même chaîne cryptée. Je ne suis pas sûr de savoir si cela encodèle ou non, mais je n'ai jamais rencontré ce problème en acceptant des chaînes chiffrées depuis n'importe quel autre système avant, alors j'espère que c'est comme je suis chiffré dans CryptoJS qui est 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> 

    Il semble y avoir deux problèmes:

    1. CryptoJS n'utilise pas votre variable comme key . Comme l'a mentionné Miguel-F, lorsque vous passez une chaîne, "il est traité comme une phrase secrète et utilisé pour dériver [la] clé réelle et IV" . Les deux sont générés au hasard, c'est pourquoi votre résultat chiffré continue de changer. Mais plus important encore, cela signifie que CryptoJS utilise une key complètement différente de celle de votre code CF et c'est pourquoi le décryptage () échoue. (Au moins, cela fait partie de la raison …)

    2. Le deuxième problème est que, en plus de l'algorithme "AES", il existe deux autres paramètres de cryptage qui doivent correspondre: le mode et le schéma de rembourrage . Alors que CryptoJS et ColdFusion utilisent les mêmes valeurs par défaut pour le système de rembourrage, les "modes" sont différents:

      • ColdFusion utilise "ECB" . "AES" est réellement court pour "AES/ECB/PKCS5Padding"
      • CryptoJS utilise "CBC", qui nécessite une valeur iv supplémentaire ( vecteur d'initialisation ).

    Vous devez vous assurer que les trois paramètres sont les mêmes des deux côtés. Essayez d'utiliser le mode CBC dans CF, car il est plus sécurisé que la BCE de toute façon. Remarque: il faut ajouter une valeur IV.

    Code CF:

     <!--- 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: (Exemple original ajusté)

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

    Modifier:

    Tout ce qui a dit, que voulez-vous dire par le client "n'a d'autre choix que d'utiliser CryptoJS pour effectuer le cryptage" ? Pourquoi ne peuvent-ils pas utiliser le cryptage côté serveur? Je ne suis pas un expert en cryptage, mais le cryptage en javascript et l' affichage de la clé sur le client ne semble pas être extrêmement sécurisé pour commencer …