CryptoJS和Pycrypto一起工作 [英] CryptoJS and Pycrypto working together

查看:118
本文介绍了CryptoJS和Pycrypto一起工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用CryptoJS(v 2.3)在Web应用程序中对字符串进行加密,并且需要在Python的服务器上对其进行解密,因此我在使用PyCrypto。我感觉好像丢失了一些东西,因为它无法正常工作。



以下是JS:

  Crypto.AES.encrypt('1234567890123456','1234567890123456',
{mode:new Crypto.mode.CBC(Crypto.pad.ZeroPadding )})
//输出: wRbCMWcWbDTmgXKCjQ3Pd // aRasZ4mQr57DgTfIvRYE =

Python:

 来自Crypto.Cipher导入AES 
导入base64
解密器= AES .new('1234567890123456',AES.MODE_CBC)
cryptor.decrypt(base64.b64decode( wRbCMWcWbDTmgXKCjQ3Pd // aRasZ4mQr57DgTfIvRYE =))
#输出:'\xd0\xc2\x1 \xbb\xf1\xf2\x9a\xb9\xb6\xdc\x15l\xe7\xf3\xfa\xed\xe4\xf5j\x826\xde(m\ \xdf\xdc_\x9e\xd3\xb1'


解决方案

这里是CryptoJS 3.1.2的版本,请务必当心以下内容(两种语言使用相同的内容):




  • 操作模式(在这种情况下为CBC)

  • 填充(在这种情况下为零填充;最好使用PKCS#7填充)

  • 密钥(相同的派生函数或清除密钥)

  • 编码(密钥,明文,密文, ...)

  • IV(在加密过程中生成,传递给解密)



  • 如果a字符串作为 key 参数传递给CryptoJS encrypt()函数,该字符串用于派生实际密钥用于加密。如果希望使用密钥(有效大小为16、24和32字节),则需要将其作为WordArray传递。



    CryptoJS加密的结果是OpenSSL格式的密文字符串。要从中获取实际的密文,需要访问其上的密文属性。



    IV必须为每种加密都是随机的,因此在语义上是安全的。这样,攻击者仅查看密文就无法说出多次加密的同一个明文是否实际上是同一个明文。



    下面是我的一个例子。



    JavaScript:

      var键= CryptoJS.enc.Utf8.parse('1234567890123456'); // TODO更改为具有更大熵的东西

    函数crypto(msgString,key){
    // msgString应该是Utf8编码的
    var iv = CryptoJS.lib.WordArray .random(16);
    var crypto = CryptoJS.AES.encrypt(msgString,key,{
    iv:iv
    });
    return iv.concat(encrypted.ciphertext).toString(CryptoJS.enc.Base64);
    }

    函数delete(ciphertextStr,key){
    var ciphertext = CryptoJS.enc.Base64.parse(ciphertextStr);

    //分割IV和密文
    var iv = ciphertext.clone();
    iv.sigBytes = 16;
    iv.clamp();
    ciphertext.words.splice(0,4); //删除4个字= 16个字节
    ciphertext.sigBytes-= 16;

    //解密
    var已解密= CryptoJS.AES.decrypt({ciphertext:ciphertext},key,{
    iv:iv
    });
    返回解密的.toString(CryptoJS.enc.Utf8);
    }

    Python代码:



    < pre class = lang-py prettyprint-override> BLOCK_SIZE = 16
    键= b 1234567890123456#TODO更改为具有更大熵的内容

    def pad( data):
    length = BLOCK_SIZE-(len(data)%BLOCK_SIZE)
    返回数据+ chr(length)* length

    def unpad(data):
    返回数据[:-ord(数据[-1])]

    def加密(消息,密钥):
    IV = Random.new()。read(BLOCK_SIZE)
    aes = AES.new(密钥,AES.MODE_CBC,IV)
    返回base64.b64encode(IV + aes.encrypt(pad(message)))

    def解密(加密密钥) :
    已加密= base64.b64decode(已加密)
    IV =已加密[:BLOCK_SIZE]
    aes = AES.new(key,AES.MODE_CBC,IV)
    return unpad(aes .decrypt(encrypted [BLOCK_SIZE:]))






    其他注意事项:



    您似乎想使用密码短语作为密钥。密码短语通常是人类可读的,但密钥却不可读。您可以从具有PBKDF2,bcrypt或scrypt之类的功能的密码短语中获取密钥。



    上面的代码并不完全安全,因为它没有身份验证。未经身份验证的密文可能导致可行的攻击和未经注意的数据处理。通常,采用先加密然后再加密(MAC)方案,并具有良好的MAC功能,例如HMAC-SHA256。


    I'm encrypting a string in a web application using CryptoJS (v 2.3), and I need to decrypt it on the server in Python, so I'm using PyCrypto. I feel like I'm missing something because I can't can it working.

    Here's the JS:

    Crypto.AES.encrypt('1234567890123456', '1234567890123456',
                       {mode: new Crypto.mode.CBC(Crypto.pad.ZeroPadding)})
    // output: "wRbCMWcWbDTmgXKCjQ3Pd//aRasZ4mQr57DgTfIvRYE="
    

    The python:

    from Crypto.Cipher import AES
    import base64
    decryptor = AES.new('1234567890123456', AES.MODE_CBC)
    decryptor.decrypt(base64.b64decode("wRbCMWcWbDTmgXKCjQ3Pd//aRasZ4mQr57DgTfIvRYE="))
    # output: '\xd0\xc2\x1ew\xbb\xf1\xf2\x9a\xb9\xb6\xdc\x15l\xe7\xf3\xfa\xed\xe4\xf5j\x826\xde(m\xdf\xdc_\x9e\xd3\xb1'
    

    解决方案

    Here is a version with CryptoJS 3.1.2. Always beware of the following things (use the same in both languages):

    • Mode of operation (CBC in this case)
    • Padding (Zero Padding in this case; better use PKCS#7 padding)
    • Key (the same derivation function or clear key)
    • Encoding (same encoding for key, plaintext, ciphertext, ...)
    • IV (generated during encryption, passed for decryption)

    If a string is passed as the key argument to the CryptoJS encrypt() function, the string is used to derive the actual key to be used for encryption. If you wish to use a key (valid sizes are 16, 24 and 32 byte), then you need to pass it as a WordArray.

    The result of the CryptoJS encryption is an OpenSSL formatted ciphertext string. To get the actual ciphertext from it, you need to access the ciphertext property on it.

    The IV must be random for each encryption so that it is semantically secure. That way attackers cannot say whether the same plaintext that was encrypted multiple times is actually the same plaintext when only looking at the ciphertext.

    Below is an example that I have made.

    JavaScript:

    var key = CryptoJS.enc.Utf8.parse('1234567890123456'); // TODO change to something with more entropy
    
    function encrypt(msgString, key) {
        // msgString is expected to be Utf8 encoded
        var iv = CryptoJS.lib.WordArray.random(16);
        var encrypted = CryptoJS.AES.encrypt(msgString, key, {
            iv: iv
        });
        return iv.concat(encrypted.ciphertext).toString(CryptoJS.enc.Base64);
    }
    
    function decrypt(ciphertextStr, key) {
        var ciphertext = CryptoJS.enc.Base64.parse(ciphertextStr);
    
        // split IV and ciphertext
        var iv = ciphertext.clone();
        iv.sigBytes = 16;
        iv.clamp();
        ciphertext.words.splice(0, 4); // delete 4 words = 16 bytes
        ciphertext.sigBytes -= 16;
    
        // decryption
        var decrypted = CryptoJS.AES.decrypt({ciphertext: ciphertext}, key, {
            iv: iv
        });
        return decrypted.toString(CryptoJS.enc.Utf8);
    }
    

    Python code:

    BLOCK_SIZE = 16
    key = b"1234567890123456" # TODO change to something with more entropy
    
    def pad(data):
        length = BLOCK_SIZE - (len(data) % BLOCK_SIZE)
        return data + chr(length)*length
    
    def unpad(data):
        return data[:-ord(data[-1])]
    
    def encrypt(message, key):
        IV = Random.new().read(BLOCK_SIZE)
        aes = AES.new(key, AES.MODE_CBC, IV)
        return base64.b64encode(IV + aes.encrypt(pad(message)))
    
    def decrypt(encrypted, key):
        encrypted = base64.b64decode(encrypted)
        IV = encrypted[:BLOCK_SIZE]
        aes = AES.new(key, AES.MODE_CBC, IV)
        return unpad(aes.decrypt(encrypted[BLOCK_SIZE:]))
    


    Other considerations:

    It seems that you want to use a passphrase as a key. Passphrases are usually human readable, but keys are not. You can derive a key from a passphrase with functions such as PBKDF2, bcrypt or scrypt.

    The code above is not fully secure, because it lacks authentication. Unauthenticated ciphertexts may lead to viable attacks and unnoticed data manipulation. Usually the an encrypt-then-MAC scheme is employed with a good MAC function such as HMAC-SHA256.

    这篇关于CryptoJS和Pycrypto一起工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆