python chr加密,用python加密-用JavaScript解密

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

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 )

this is producing text: ZF9as5JII5TlqcB5tAd4sxPuBXd5TrgE

in JavaScript:

var decrypted = CryptoJS.AES.decrypt( "ZF9as5JII5TlqcB5tAd4sxPuBXd5TrgE", "1234567890123456");

console.log ( decrypted.toString( CryptoJS.enc.Utf8 ) );

however it does not produce original string (empty string instead).

What I am doing wrong ?

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

解决方案

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

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.

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.

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.

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

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 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 code:

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

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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值