用python加密-用JavaScript解密 [英] Encrypt in python - decrypt in Javascript

查看:438
本文介绍了用python加密-用JavaScript解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要简单地在python中加密一些文本并能够在JavaScrypt中解密。

I have need to simply encrypt some text in python and being able to decrypt in JavaScrypt.

到目前为止,我在python中已经拥有:

So far I have in python:

from Crypto import Random
from Crypto.Cipher import AES
import base64

BLOCK_SIZE = 16
key = "1234567890123456" # want to be 16 chars
textToEncrypt = "This is text to encrypt"

def encrypt(message, passphrase):
    # passphrase MUST be 16, 24 or 32 bytes long, how can I do that ?
    IV = Random.new().read(BLOCK_SIZE)
    aes = AES.new(passphrase, AES.MODE_CFB, IV)
    return base64.b64encode(aes.encrypt(message))

def decrypt(encrypted, passphrase):
    IV = Random.new().read(BLOCK_SIZE)
    aes = AES.new(passphrase, AES.MODE_CFB, IV)
    return aes.decrypt(base64.b64decode(encrypted))

print encrypt( textToEncrypt, key )

正在生成文本: ZF9as5JII5TlqcB5tAd4sxPuBXd5TrgE

在JavaScript中:

in JavaScript:

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script>
    var decrypted = CryptoJS.AES.decrypt( "ZF9as5JII5TlqcB5tAd4sxPuBXd5TrgE", "1234567890123456");
    console.log ( decrypted.toString( CryptoJS.enc.Utf8 ) );
</script>

但是它不会产生原始字符串(而是空字符串)。
我在做什么错了?

however it does not produce original string (empty string instead). What I am doing wrong ?

专注于AES是否是一个好主意-如果我使用某种会模糊数据的加密,我会很高兴。

Is it focusing on AES is a best idea - I will be happy if I have some kind of encryption that will blur data.

推荐答案

Python代码 CryptoJS代码存在很多问题:

There are many problems with your Python code and CryptoJS code:


  • 您使用随机IV加密Python中的某些纯文本。如果要检索该纯文本,则需要在解密期间使用相同的IV 。没有IV,纯文本将无法恢复。通常,IV只是在密文的前面,因为它不一定是秘密的。因此,您需要在解密过程中读取IV,而不要生成新的IV。

  • You use a random IV to encrypt some plaintext in Python. If you want to retrieve that plaintext, you need to use the same IV during decryption. The plaintext cannot be recovered without the IV. Usually the IV is simply prepended to the ciphertext, because it doesn't have to be secret. So you need to read the IV during decryption and not generate a new one.

您在CryptoJS(默认)中使用CBC模式而不是CFB模式。模式必须相同。另一个棘手的部分是CFB模式是用段大小参数化的。 PyCrypto默认使用8位段(CFB8),但CryptoJS仅对128位固定段(CFB128)实现。由于PyCrypto版本是可变的,因此您需要更改它。

You use CBC mode in CryptoJS (default) instead of CFB mode. The mode has to be the same. The other tricky part is that CFB mode is parametrized with a segment size. PyCrypto uses by default 8-bit segments (CFB8), but CryptoJS is only implemented for fixed segments of 128-bit (CFB128). Since the PyCrypto version is variable, you need to change that.

CryptoJS decrypt()函数期望使用OpenSSL格式的字符串或CipherParams对象作为密文。由于没有OpenSSL格式的字符串,因此必须将密文转换为对象。

The CryptoJS decrypt() function expects as ciphertext either an OpenSSL formatted string or a CipherParams object. Since you don't have an OpenSSL formatted string, you have to convert the ciphertext into an object.

key 应该是一个WordArray,而不是字符串。

The key for CryptoJS is expected to be a WordArray and not a string.

使用相同的填充。如果使用CFB8,PyCrypto不会填充明文,但使用CFB128时则需要填充。 CryptoJS默认使用PKCS#7填充,因此您只需要在python中实现该填充。

Use the same padding. PyCrypto doesn't pad the plaintext if CFB8 is used, but padding is needed when CFB128 is used. CryptoJS uses PKCS#7 padding by default, so you only need to implement that padding in python.

Python代码(对于版本2):

Python code (for version 2):

def pad(data):
    length = 16 - (len(data) % 16)
    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_CFB, IV, segment_size=128)
    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_CFB, IV, segment_size=128)
    return unpad(aes.decrypt(encrypted[BLOCK_SIZE:]))

JavaScript代码:

JavaScript code:

<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/aes.js"></script>
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/components/mode-cfb-min.js"></script>
<script>
    var base64ciphertextFromPython = "...";
    var ciphertext = CryptoJS.enc.Base64.parse(base64ciphertextFromPython);

    // 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;

    var key = CryptoJS.enc.Utf8.parse("1234567890123456");

    // decryption
    var decrypted = CryptoJS.AES.decrypt({ciphertext: ciphertext}, key, {
      iv: iv,
      mode: CryptoJS.mode.CFB
    });
    console.log ( decrypted.toString(CryptoJS.enc.Utf8));
</script>






其他注意事项:

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

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.

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

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.

这篇关于用python加密-用JavaScript解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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