2012-07-19 3 views
0

Я шифрую строку в веб-приложении с использованием CryptoJS (v 2.3), и мне нужно расшифровать ее на сервере в 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 обивка)
  • Key (та же функция, вывод или прозрачный ключ)
  • Encoding (кодирование же для ключа, открытого текста, зашифрованного, ...)
  • IV (генерируется во время шифрования, принятый для расшифровки)

Если строка передана как аргумент key функции 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

Поправьте меня, если я ошибаюсь, но я не вижу нигде отступы в коде питона

+0

Вы правы – ian

Смежные вопросы