2012-08-31 135 views
0
from Crypto.Cipher import AES 
import os 

key = 'mysecretpassword' 
iv = os.urandom(16) 
plaintext1 = 'Secret Message A' 
encobj = AES.new(key, AES.MODE_CBC, iv) 
ciphertext1 = encobj.encrypt(plaintext1) 
encryptedText = ciphertext1.encode('base64') 
print encryptedText 
decobj = AES.new(key, AES.MODE_CBC, iv) 
print decobj.decrypt(ciphertext1) 

我從我的代碼複製了encryptedTextkey的打印值並粘貼到下面的網站。爲什麼我不能解密我的AES加密的消息在別人的AES密碼解密器上?

http://www.everpassword.com/aes-encryptor

http://www.nakov.com/blog/2011/12/26/online-aes-encryptor-decryptor-javascript/

我會希望它是能夠解密密我,但事實並非如此。因此我必須使用pycrypto錯誤。我該如何解決?這兩個站點可以相互加密和解密,但地雷不能。這兩個網站確實使用CBC模式。

+0

你嘗試過不同的模式嗎?我看不到該網站是使用XTS,CBC還是僅使用ECB。嘗試不同的模式。請注意,您使用IV,但該網站不會要求提供一個。 – javex

+3

你需要給解密器IV。該網站不接受IV。所以它可能使用ECB,而不是CBC。 –

+1

另外,你如何知道該網站將密文作爲base64? –

回答

3

如果您查看相關網站的頁面源代碼,您將看到它使用了gibberish-aes javascript庫。要看到你需要做什麼才能使其發揮作用,你必須研究它的功能。

翻看它的source code,它似乎使用隨機鹽進行加密。這個由字符串Salted__作爲前綴的格式在基本編碼之前形成了密碼文本的開始。

randArr = function(num) { 
    var result = [], i; 
    for (i = 0; i < num; i++) { 
     result = result.concat(Math.floor(Math.random() * 256)); 
    } 
    return result; 
}, 

enc = function(string, pass, binary) { 
     // string, password in plaintext 
     var salt = randArr(8), 
     pbe = openSSLKey(s2a(pass, binary), salt), 
     key = pbe.key, 
     iv = pbe.iv, 
     cipherBlocks, 
     saltBlock = [[83, 97, 108, 116, 101, 100, 95, 95].concat(salt)]; 
     string = s2a(string, binary); 
     cipherBlocks = rawEncrypt(string, key, iv); 
     // Spells out 'Salted__' 
     cipherBlocks = saltBlock.concat(cipherBlocks); 
     return Base64.encode(cipherBlocks); 
    }, 

對於解密,它使用拾取鹽的隨機部分出來的密文的開始BASE64解碼(第一slice運算符)之後:

dec = function(string, pass, binary) { 
    // string, password in plaintext 
    var cryptArr = Base64.decode(string), 
    salt = cryptArr.slice(8, 16), 
    pbe = openSSLKey(s2a(pass, binary), salt), 
    key = pbe.key, 
    iv = pbe.iv; 
    cryptArr = cryptArr.slice(16, cryptArr.length); 
    // Take off the Salted__ffeeddcc 
    string = rawDecrypt(cryptArr, key, iv, binary); 
    return string; 
}, 

現在缺失的部分是openSSLkey功能:

openSSLKey = function(passwordArr, saltArr) { 
    // Number of rounds depends on the size of the AES in use 
    // 3 rounds for 256 
    // 2 rounds for the key, 1 for the IV 
    // 2 rounds for 128 
    // 1 round for the key, 1 round for the IV 
    // 3 rounds for 192 since it's not evenly divided by 128 bits 
    var rounds = Nr >= 12 ? 3: 2, 
    key = [], 
    iv = [], 
    md5_hash = [], 
    result = [], 
    data00 = passwordArr.concat(saltArr), 
    i; 
    md5_hash[0] = GibberishAES.Hash.MD5(data00); 
    result = md5_hash[0]; 
    for (i = 1; i < rounds; i++) { 
     md5_hash[i] = GibberishAES.Hash.MD5(md5_hash[i - 1].concat(data00)); 
     result = result.concat(md5_hash[i]); 
    } 
    key = result.slice(0, 4 * Nk); 
    iv = result.slice(4 * Nk, 4 * Nk + 16); 
    return { 
     key: key, 
     iv: iv 
    }; 
}, 

所以基本上你必須將openSSLKey函數翻譯成Python,併爲它提供密碼和鹽。這會創建一個(key,iv)元組。使用這些來加密您的數據。將字符串Salted__和salt加密到使用base64進行編碼之前。那麼它應該工作,我想。