简体   繁体   English

使用CryptoJS在javascript中进行AES加密/解密

[英]AES encryption/decryption in javascript using CryptoJS

I am trying to send AES encrypted messages between javascript and php using a shared secret. 我正在尝试使用共享密钥在javascript和php之间发送AES加密消息。 In Javascript I am using the CryptoJS library. 在Javascript中,我正在使用CryptoJS库。 In php, I am using mycrypt. 在php中,我正在使用mycrypt。 I am trying to construct an encrypted message in javascript and then decrypt it in php using the shared secret. 我试图在javascript中构造一个加密的消息,然后使用共享密钥在php中对其解密。 I can encrypt and decrypt a message in Javascript. 我可以用Javascript加密和解密消息。 I can encrypt and decrypt the same message in php - but the encryption is not the same between the two. 我可以在php中加密和解密相同的消息-但两者之间的加密并不相同。

The Javascript Javascript

var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");
alert(encrypted);

Gives

U2FsdGVkX18+k3pba4l4MbGZfmDjMc1yQ6uj1fg+BGo= U2FsdGVkX18 + k3pba4l4MbGZfmDjMc1yQ6uj1fg + BGO =

In php 在PHP中

<?php
$Pass = "Secret Passphrase";
$Clear = "Message";

$crypted = fnEncrypt($Clear, $Pass);
echo "Encrypted: ".$crypted."</br>";

$newClear = fnDecrypt($crypted, $Pass);
echo "Decrypted: ".$newClear."</br>";

function fnEncrypt($sValue, $sSecretKey) {
return rtrim(
        base64_encode(
                mcrypt_encrypt(
                        MCRYPT_RIJNDAEL_256,
                        $sSecretKey, $sValue,
                        MCRYPT_MODE_ECB,
                        mcrypt_create_iv(
                                mcrypt_get_iv_size(
                                        MCRYPT_RIJNDAEL_256,
                                        MCRYPT_MODE_ECB
                                ),
                                MCRYPT_RAND
                        )
                )
        ),"\0"
);
}

function fnDecrypt($sValue, $sSecretKey) {
return rtrim(
        mcrypt_decrypt(
                MCRYPT_RIJNDAEL_256,
                $sSecretKey,
                base64_decode($sValue),
                MCRYPT_MODE_ECB,
                mcrypt_create_iv(
                        mcrypt_get_iv_size(
                                MCRYPT_RIJNDAEL_256,
                                MCRYPT_MODE_ECB
                        ),
                        MCRYPT_RAND
                )
        ),"\0"
);
}

The output is 输出是

Encrypted: iqJ0R5ahRP7GpWKtW7+OBSCGnudDr99VbJC36OQlmgE= 加密:iqJ0R5ahRP7GpWKtW7 + OBSCGnudDr99VbJC36OQlmgE =

Decrypted: Message 解密:消息

My question is, why are these not the same? 我的问题是,为什么这些不一样?

It would be a crypographic catastrophy if they would be the same... 如果它们相同的话,将是低温冷冻大地震。

However: Using the way you used your PHP Encryption (using EBC mode) you will always get the same result. 但是:使用您的PHP加密方式(使用EBC模式),您将始终获得相同的结果。 You can see why this is a problem by looking at the tux pciture at http://en.wikipedia.org/wiki/Cipher_block_chaining#Electronic_codebook_.28ECB.29 您可以在http://en.wikipedia.org/wiki/Cipher_block_chaining#Electronic_codebook_.28ECB.29上查看燕尾服的特性,以查看为什么这是一个问题。

CryptoJS seems to use CBC as a default block cipher mode (at least they say so in https://code.google.com/p/crypto-js/#Block_Modes_and_Padding ), which has a random initial vector. CryptoJS似乎使用CBC作为默认的分组密码模式(至少他们在https://code.google.com/p/crypto-js/#Block_Modes_and_Padding中这样说),它具有一个随机的初始向量。 This is better than CBC. 这比CBC好。

The result should be the same, if you use the same cipher, the same block cipher mode (eg CBC) and the same key and IV - and of course the same plaintext - the comments indicate that there also might be a unicode issue. 结果应该是相同的,如果您使用相同的密码,相同的分组密码模式(例如CBC)以及相同的密钥和IV(当然还有相同的纯文本),则注释表明也可能存在unicode问题。

Additionally the MCRYPT_RIJNDAEL_256 is not AES. 此外,MCRYPT_RIJNDAEL_256不是AES。 AES has a BLOCK size of 16 byte - AES-128 has a KEY size of 16 byte, AES-256 has a KEY size of 32 byte. AES的BLOCK大小为16字节-AES-128的KEY大小为16字节,AES-256的KEY大小为32字节。 MCRYPT_RIJNDAEL_256 has a BLOCK size of 32 byte - that's a big difference. MCRYPT_RIJNDAEL_256的BLOCK大小为32字节-差异很大。

One last note: It is not enough to encrypt data! 最后一点:加密数据还不够! You must also authenticate it, by either using a HMAC or by using an authenticated block cipher mode like GCM - if you don't do this you may be vulnerable to at least a padding oracle attack: http://en.wikipedia.org/wiki/Padding_oracle_attack 您还必须通过使用HMAC或使用经过身份验证的块密码模式(例如GCM)对它进行身份验证-如果不这样做,则可能至少会遭受填充oracle攻击: http : //en.wikipedia.org /维基/ Padding_oracle_attack

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM