Tab*_*iko 17 python encryption
我想知道如何使用生成的salt密钥加密数据,然后使用python解密它?
我已经通过很多网站和模块,他们看起来都很好看加密部分,但没有人可以解密.
我主要担心的是有很强的盐密钥,可能会在很短的时间内生成,然后使用该密钥加密数据 - 特别是我正在研究使用salt密钥加密JSON编码数据,将加密数据发送到另一方(侦听客户端)然后根据用于生成salt密钥的算法解密那里的数据.
我发现mcrypt模块在这方面效果最好,但是没有太多关于python-mcrypt模块的文档(目前它已经过时而没有维护).
101*_*100 44
对您的问题的简短回答是,您将密码和salt组合在一起并重复哈希以创建密钥.然后将salt附加到密文上,以便生成解密密钥.为了确保我有正确的答案,我做了一些功能来完成工作.它们如下.
在我的回答中,我已经使用了pycrypto,所以我们需要导入一些这些库.
import Crypto.Random
from Crypto.Cipher import AES
import hashlib
Run Code Online (Sandbox Code Playgroud)
为了提高可读性,我已经定义了一些我将在稍后使用的常量.
# 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
Run Code Online (Sandbox Code Playgroud)
为了使用salt,我已经完成了基于密码的加密方案.我使用RSA PKCS#5标准进行基于密码的加密密钥生成和填充,适用于AES加密算法.
要生成密钥,密码和盐将连接在一起.此组合根据要求进行多次散列.
def generate_key(password, salt, iterations):
assert iterations > 0
key = password + salt
for i in range(iterations):
key = hashlib.sha256(key).digest()
return key
Run Code Online (Sandbox Code Playgroud)
要填充文本,你可以计算出除了16的偶数之外还有多少额外字节.如果是0,则添加16字节的填充,如果是1,则添加15,等等.这样你总是添加填充.您填充的字符是与填充字节数(chr(padding_size))的值相同的字符,以帮助删除末尾的填充(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
Run Code Online (Sandbox Code Playgroud)
加密需要生成随机盐并将其与密码一起使用以生成加密密钥.使用上述pad_text函数填充文本,然后使用密码对象加密.密文和盐连接在一起并返回.如果您想以纯文本格式发送,则需要使用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
Run Code Online (Sandbox Code Playgroud)
解密继续进行,从密文中拉出盐并使用它来解密密文的其余部分.然后明文用unpadded 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
Run Code Online (Sandbox Code Playgroud)
如果您有任何其他问题/说明,请与我们联系.
除了RNCryptor之外,您不需要其他任何东西:
Run Code Online (Sandbox Code Playgroud)import rncryptor data = '...' password = '...' # rncryptor.RNCryptor's methods cryptor = rncryptor.RNCryptor() encrypted_data = cryptor.encrypt(data, password) decrypted_data = cryptor.decrypt(encrypted_data, password) assert data == decrypted_data # rncryptor's functions encrypted_data = rncryptor.encrypt(data, password) decrypted_data = rncryptor.decrypt(encrypted_data, password) assert data == decrypted_data
它提供了语义上安全的加密(每种加密均使用随机盐和IV)加密,并包括通过HMAC进行的安全完整性检查(密文无法在不注意的情况下进行操作)。
RNCryptor也有一种特定的数据格式,因此您不必考虑它和许多语言的实现。
| 归档时间: |
|
| 查看次数: |
28205 次 |
| 最近记录: |