python代码加密解密_用盐加密/解密python中的数据

1586010002-jmsa.png

I'd like to know basically how can I encrypt data with a generated salt key and then decrypt it using python ?

i've gone trough a lot of websites and modules, and they all look great at encrpytion part, but none can decrypt as it seems.

My main concern is to have strong salt key, that'd be probably generated over few hunderd times, then use that key to encrypt data - in particular I'm looking into encrypting JSON encoded data with the salt key, sending the encrypted data to the other side ( listening client ) and then decrypt the data there based on the algorithm that is used to generate the salt key.

I've found that mcrypt module would work best with this, but there isn't much documentation for python-mcrypt module ( that's currently being outdated and not maintained).

解决方案

The short answer to your question is that you combine the password and the salt and hash them repeatedly to create your key. Then you append the salt onto the ciphertext so that you can generate the key for decryption. To ensure that I had the right answer, I made a few functions to do the work. They are given below.

In my answer, I've made use of pycrypto, so we need to import a few of those libraries.

import Crypto.Random

from Crypto.Cipher import AES

import hashlib

To aid readability, I've defined a few constants that I'll use later on.

# salt size in bytes

SALT_SIZE = 16

# number of iterations in the key generation

NUMBER_OF_ITERATIONS = 20

# the size multiple required for AES

AES_MULTIPLE = 16

To use a salt, I've done a password-based encryption scheme. I've used the RSA PKCS #5 standard for password-based encryption key generation and padding, adapted for the AES encryption algorithm.

To generate the key, the password and the salt are concatenated. This combination is hashed as many times as requested.

def generate_key(password, salt, iterations):

assert iterations > 0

key = password + salt

for i in range(iterations):

key = hashlib.sha256(key).digest()

return key

To pad the text, you figure out how many extra bytes you have beyond an even multiple of 16. If it is 0, you add 16 bytes of padding, if it is 1, you add 15, etc. This way you always add padding. The character you pad with is the character with the same value as the number of padding bytes (chr(padding_size)), to aid the removal of the padding at the end (ord(padded_text[-1])).

def pad_text(text, multiple):

extra_bytes = len(text) % multiple

padding_size = multiple - extra_bytes

padding = chr(padding_size) * padding_size

padded_text = text + padding

return padded_text

def unpad_text(padded_text):

padding_size = ord(padded_text[-1])

text = padded_text[:-padding_size]

return text

Encryption requires generating a random salt and using that along with the password to generate the encryption key. The text is padded using the above pad_text function and then encrypted with a cipher object. The ciphertext and salt are concatenated and returned as a result. If you wanted to send this as plaintext, you would need to encode it with base64.

def encrypt(plaintext, password):

salt = Crypto.Random.get_random_bytes(SALT_SIZE)

key = generate_key(password, salt, NUMBER_OF_ITERATIONS)

cipher = AES.new(key, AES.MODE_ECB)

padded_plaintext = pad_text(plaintext, AES_MULTIPLE)

ciphertext = cipher.encrypt(padded_plaintext)

ciphertext_with_salt = salt + ciphertext

return ciphertext_with_salt

Decryption proceeds backwards, pulling the salt off of the ciphertext and using that to decrypt the remainder of the ciphertext. Then the plaintext is unpadded using unpad_text.

def decrypt(ciphertext, password):

salt = ciphertext[0:SALT_SIZE]

ciphertext_sans_salt = ciphertext[SALT_SIZE:]

key = generate_key(password, salt, NUMBER_OF_ITERATIONS)

cipher = AES.new(key, AES.MODE_ECB)

padded_plaintext = cipher.decrypt(ciphertext_sans_salt)

plaintext = unpad_text(padded_plaintext)

return plaintext

Let me know if you have any other questions/clarifications.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值