gpt4 book ai didi

Python 3.2 - CBC 模式下的对称 AES 加密 - 请求建议

转载 作者:行者123 更新时间:2023-12-01 05:29:47 24 4
gpt4 key购买 nike

我的目标是使用 python 3.x 设置简单的加密,所以这个周末我在网上搜索了有关 RSA/AES 等的信息......实际上,看起来可能是加密文本数据的可能性以合理安全的方式传输..也没有偏执,我不是专家,只是想确保这些内容在没有 key 的情况下很难阅读!

老实说,我对密码学了解不多。经过几个小时的搜索和收集信息和源代码后,由于 Python 2.7 中提供的示例导致无效长度问题或其他转换错误,我的尝试失败了。我发现 python 3 中的示例很少,并且使用的加密方法似乎不太合适或不认真。

我终于能够运行以下接受 ISO 8859-1 编码字符的代码。我实际上将所有内容封装为 UTF-8 编码以避免语言问题..我希望如此..

我想知道我的设计方式是否正确,特别是数据安全性是否可以接受,我并不是在寻找出色的安全解决方案,只是想保护我自己的个人数据而不是保护军事防御 secret 哈哈!

请随时向我转发您的意见或建议,尤其是我可能错过的事情!

非常感谢您的提前。

伊曼纽尔(法国)

注意:下一步我将尝试将 RSA 加密的 AES 密码与文本流一起发送给收件人。由于每条消息的 AES 密码都不同,客户端需要自动翻译它才能解码密码消息。 AES 密码将以 RSA 非对称加密方式使用尽可能最强的 key 进行传输,而不会影响性能。目的是在合理的时间范围内传输简单的消息(无需 Base64 编码)或大量数据。

@+再见。

要执行下面的代码,您应该安装 PyCrypto (python 3.2)

import os, base64, hashlib
from Crypto.Cipher import AES

class Aes(object):

# Crypte / décrypte un texte donné en AES mode CBC. Accepte l'encodage base64.
# Encrypts input text string & decrypts bytes encoded string with or without base64 encoding
# Author: emmanuel.brunet@live.fr - 12/2013


SALT_LENGTH = 64
DERIVATION_ROUNDS=10000
BLOCK_SIZE = 16
KEY_SIZE = 256
MODE = AES.MODE_CBC

def encrypt(self, source, aes_key, outfile=None, base64_encode=False):
'''
Crypte l'entrée source en AES mode CBC avec sortie encodage base64 / fichier facultative

@param str source: text to encode or text file path
@param bytes aes_key: password
@parm str outfile: disk file to write encoded text to. defaults to None
@param bool base64_encode: returns base64 encoded string if True (for emails) or bytes if False

@return bytes ciphertext: the bytes encoded string.
'''


'''
----------------------------
Inputs management
----------------------------
'''
if os.path.exists(source):

fp = open(source, 'rb')
input_text = fp.read()
fp.close()

else:

input_text = bytes(source, 'UTF-8')

if input_text == b'':
print('No data to encrypt')
return

padding_len = 16 - (len(input_text) % 16)
padded_text = str(input_text, 'UTF-8') + chr(padding_len) * padding_len

'''
---------------------------------------------------------
Computes the derived key (derived_key).
---------------------------------------------------------
Elle permet d'utiliser la clé initiale (aes_key) plusieurs
fois, une pour chaque bloc à encrypter.
---------------------------------------------------------
'''

salt = os.urandom(self.SALT_LENGTH)

derived_key = bytes(aes_key, 'UTF-8')

for unused in range(0,self.DERIVATION_ROUNDS):

derived_key = hashlib.sha256(derived_key + salt).digest()

derived_key = derived_key[:self.KEY_SIZE]

'''
----------------
Encrypt
----------------
'''
# The initialization vector should be random
iv = os.urandom(self.BLOCK_SIZE)

cipherSpec = AES.new(derived_key, self.MODE, iv)
cipher_text = cipherSpec.encrypt(padded_text)
cipher_text = cipher_text + iv + salt

'''
-------------------------
Output management
-------------------------
'''
if outfile is None:
'''
Returns cipher in base64 encoding. Useful for email management for instance
'''
if base64_encode:
return(base64.b64encode(cipher_text))
else:
return(cipher_text)

else:
'''
Writes result to disk
'''

fp = open(outfile, 'w')

if base64_encode:
fp.write(base64.b64encode(cipher_text))
else:
fp.write(cipher_text)

fp.close()

print('Cipher text saved in', outfile)


def decrypt(self, source, aes_key, outfile=None, base64_encode=False):
'''
Decrypts encoded string or data file

@param bytes or str source: encrypted bytes string to decode or file path
@param bytes aes_key: password
@parm str outfile: disk file to write encoded text to. defaults to None
@param bool base64_encode: cipher text is given base64 encoded (for mails content for examples)

@returns str secret_text: the decoding text string or None if invalid key given
'''

'''
---------------------------
Input management
---------------------------
'''

if type(source) == str and os.path.exists(source):

fp = open(source, 'rb')
ciphertext = fp.read()
fp.close()

elif type(source) == bytes:
ciphertext = source

else:
print('Invalid data source')
return

if base64_encode:
encoded_text = base64.b64decode(ciphertext)
else:
# decodedCiphertext = ciphertext.decode("hex")
encoded_text = ciphertext

'''
-------------------------
Computes derived key
-------------------------
'''

iv_start = len(encoded_text) - self.BLOCK_SIZE - self.SALT_LENGTH
salt_start = len(encoded_text) - self.SALT_LENGTH
data, iv, salt = encoded_text[:iv_start], encoded_text[iv_start:salt_start], encoded_text[salt_start:]

derived_key = bytes(aes_key, 'utf-8')

for unused in range(0, self.DERIVATION_ROUNDS):
derived_key = hashlib.sha256(derived_key + salt).digest()

derived_key = derived_key[:self.KEY_SIZE]


'''
-------------------------
Decrypt
-------------------------
'''
Cipher = AES.new(derived_key, self.MODE, iv)
padded_text = Cipher.decrypt(data)

padding_length = padded_text[-1]
secret_text = padded_text[:-padding_length]

'''
Si le flux n'est pas décodé (mot de passe invalide), la conversion UTF-8 plante ou au mieux on obtient un texte illisible
'''
try:
secret_text = str(secret_text, 'utf-8')
except:
return

if outfile is None:

return(secret_text)

else:
'''
Writes result to disk
'''
fp = open(outfile, 'w')
fp.write(secret_text)
fp.close()

最后的东西

我进行了以下更改:

  • 使用 PBKDF2 作为带有 HMAC-sha512 的 KDF
  • 解决了持续存在的问题
  • 现在强制安装包:PyCypto 和 pbkdf2-1.3

我已经尝试了很多次插入新的代码块......但它不起作用。文本编辑器的行为非常奇怪。

最佳答案

你做得比我预期的要好:P。只是一些改进代码的建议:

  • 如果你使用一个好的、著名的、强大的 key 派生函数会更好,比如 PBKDF2使用 HMAC-sha256。您的 KDF 看起来很强大,但在谈论密码学时,最好依赖经过广泛审查的算法。
  • 您可以考虑使用 os.random 代替 os.urandom(或者至少可以轻松地从一种随机切换到另一种)以获得更多熵。
  • 您可以在加密输出中添加一些“ header ”,这样您就可以在不知道 key 大小和其他变量的情况下对其进行解密,而这些内容现在都是硬编码的。
  • 让用户可以更轻松地更改现在硬编码的设置。

此外,对于下一步,我建议您查看 DH key exchange 。这将为您提供完美的前向保密性。

关于Python 3.2 - CBC 模式下的对称 AES 加密 - 请求建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20494741/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com