2012-07-19 96 views
0

我使用CryptoJS(v 2.3)加密Web应用程序中的字符串,我需要在Python中的服务器上解密它,所以我使用PyCrypto。我觉得我失去了一些东西,因为我无法工作。CryptoJS和Pycrypto一起工作

这里的JS:

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

蟒蛇:

from Crypto.Cipher import AES 
import base64 
decryptor = AES.new('123456789', 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' 

回答

3

这里是CryptoJS 3.1.2的一个版本。总是提防以下事(使用相同的两种语言):

  • 操作的模式(CBC在这种情况下)
  • 填充(零填充在这种情况下,更好地利用PKCS#7填充)
  • 密钥(相同的推导函数或清除键)
  • 编码(用于密钥,明文,密文相同的编码,...)
  • IV(加密过程中产生的,通过了解密)

如果将字符串作为参数传递给CryptoJS encrypt()函数,则该字符串用于派生用于加密的实际密钥。如果你想使用一个键(有效的大小是16,24和32字节),那么你需要将它作为一个WordArray传递。

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

对于每个加密,IV必须是随机的,以便它在语义上是安全的。那样的话,攻击者无法说出只有在查看密文时,被多次加密的相同明文是否实际上是相同的明文。

的JavaScript:

var key = CryptoJS.enc.Utf8.parse('123456789'); 

function encrypt(msgString, key) { 
    // msgString is expected to be Utf8 encoded 
    var iv = CryptoJS.lib.WordArray.random(16); 
    var encrypted = Crypto.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代码:

BLOCK_SIZE = 16 
key = b"123456789" 

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, passphrase): 
    IV = Random.new().read(BLOCK_SIZE) 
    aes = AES.new(passphrase, AES.MODE_CBC, IV) 
    return base64.b64encode(IV + aes.encrypt(pad(message))) 

def decrypt(encrypted, passphrase): 
    encrypted = base64.b64decode(encrypted) 
    IV = encrypted[:BLOCK_SIZE] 
    aes = AES.new(passphrase, AES.MODE_CBC, IV) 
    return unpad(aes.decrypt(encrypted[BLOCK_SIZE:])) 

其他注意事项:

看来你要使用密码作为重点。密码通常是人类可读的,但密钥不是。您可以从密码中派生出一个密钥,其中包含PBKDF2,bcrypt或scrypt等功能。

上面的代码不完全安全,因为它缺少认证。未经验证的密文可能导致可行的攻击和未被注意的数据操纵。通常采用加密后MAC方案以及良好的MAC功能,如HMAC-SHA256。

0

纠正我,如果我错了,但我没有看到任何地方填充在Python代码

+0

你是对的 – ian 2012-07-19 19:23:14