在python3中使用用户设置的密码进行正确的数据加密



我一直在寻找一个合适的数据加密库在python中呆了很长一段时间,今天我再次需要它,不能找到任何东西,那么有什么方法可以使用用户设置的密码,如果我发现一些通常不安全的东西,如果我找到一个好的解决方案,它不支持用户设置密码,意思是我被卡住了,有什么办法吗?

这里有一些伪代码:

import encryption
encryptor: encryption.Crypt = encryption.Crypt("my secret password")
encryptor.encrypt("hello this is my very secret string")  # => 9oe gyu yp9q*(Y 28j
encryptor.decrypt("9oe gyu yp9q*(Y 28j")  # => hello this is my very secret string

我不在乎它是不是一个物体,尽管我在乎它也可以是一个接受密码的函数:

import encryption
encryption.encrypt("hello this is my very secret string", "my secret password")  # => 9oe gyu yp9q*(Y 28j
encryption.decrypt("9oe gyu yp9q*(Y 28j", "my secret password")  # => hello this is my very secret string

我不介意加密或解密的方式,我我只想找到一种方法:(,我也不想注意它的输出,它可以是二进制的,一个对象,字符串,任何

基于Sam Hartzog的回答,下面是一个遵循RFC8018第6.2节中定义的PBES2(基于密码的加密方案2(逻辑的示例。然而,它缺少编码算法的选择和参数。

#!/usr/bin/python
import base64
import secrets
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
KDF_ALGORITHM = hashes.SHA256()
KDF_LENGTH = 32
KDF_ITERATIONS = 120000
def encrypt(plaintext: str, password: str) -> (bytes, bytes):
# Derive a symmetric key using the passsword and a fresh random salt.
salt = secrets.token_bytes(16)
kdf = PBKDF2HMAC(
algorithm=KDF_ALGORITHM, length=KDF_LENGTH, salt=salt,
iterations=KDF_ITERATIONS)
key = kdf.derive(password.encode("utf-8"))
# Encrypt the message.
f = Fernet(base64.urlsafe_b64encode(key))
ciphertext = f.encrypt(plaintext.encode("utf-8"))
return ciphertext, salt
def decrypt(ciphertext: bytes, password: str, salt: bytes) -> str:
# Derive the symmetric key using the password and provided salt.
kdf = PBKDF2HMAC(
algorithm=KDF_ALGORITHM, length=KDF_LENGTH, salt=salt,
iterations=KDF_ITERATIONS)
key = kdf.derive(password.encode("utf-8"))
# Decrypt the message
f = Fernet(base64.urlsafe_b64encode(key))
plaintext = f.decrypt(ciphertext)
return plaintext.decode("utf-8")
def main():
password = "aStrongPassword"
message = "a secret message"
encrypted, salt = encrypt(message, password)
decrypted = decrypt(encrypted, password, salt)
print(f"message: {message}")
print(f"encrypted: {encrypted}")
print(f"decrypted: {decrypted}")

输出:

message: a secret message
encrypted: b'gAAAAABjDlH2eaRZmB4rduBdNHUOITV5q4oelpnLRUgI_uyQyNpUyW8h3c2lZYS1MwMpRWIZposcZvag9si1pc4IEK83_CzyBdXF27Aop9WWS6ybxTg9BSo='
decrypted: a secret message

只要稍微润滑一下,加密包(pip install cryptography(就可以很好地实现这一点。我认为,你看不到一个简单的基于OOTB字符串的实现的原因是,密码学是在字节级别上工作的,而不是字符串(可能以任何方式编码(。无论如何,以下内容似乎适用于您概述的简单用例。

创建一个"加密器"并加密某些东西

from cryptography.fernet import Fernet
import base64
entered_pw = "secretpw"
key = base64.b64encode(f"{entered_pw:<32}".encode("utf-8"))
encryptor = Fernet(key=key)
encrypted = encryptor.encrypt(
"my super secret data with a password".encode("utf-8")
)
print(encrypted)

输出:

b'gAAAAABjDVew9-VszAFP1ZdlDz-ZqwdIksCBhLbH8OEJjxEZyEy6cQ4jrxEBHZtHsGtWxHsG0qJIkQ_b5e5Ibx5-1uAa1HXdBwWys6YE7WwhmMPtAbj_VP2F8rKFck7MYvv5nKrZbWGF'

使用正确输入的密码解密结果

from cryptography.fernet import Fernet
import base64
entered_pw = "secretpw"
key = base64.b64encode(f"{entered_pw:<32}".encode("utf-8"))
encryptor = Fernet(key=key)
encrypted = b'gAAAAABjDVew9-VszAFP1ZdlDz-ZqwdIksCBhLbH8OEJjxEZyEy6cQ4jrxEBHZtHsGtWxHsG0qJIkQ_b5e5Ibx5-1uAa1HXdBwWys6YE7WwhmMPtAbj_VP2F8rKFck7MYvv5nKrZbWGF'
print(encryptor.decrypt(encrypted).decode("utf-8"))

输出:

'my super secret data with a password'

如果在解密时提供了错误的密码,则会出现InvalidSignature异常。

完全公开,我不是密码学专家,所以这可能是一个非常糟糕和不安全的方法,但它似乎是合法的\_(ツ)_/。如果有任何加密货币专家想让我承担责任,请放心…;(

试试这个小python模块作为加密的包装器

pip install pyeasyencrypt

代码示例:

import logging, os
# pip install pyeasyencrypt
from pyeasyencrypt.pyeasyencrypt import encrypt_string, decrypt_string
level = os.getenv("LOGGER", "INFO")
logging.basicConfig(level=level)
logger = logging.getLogger(__name__)
def main():
logger.info("Example")
clear_string = 'stringA'
password = "my password"
encrypted_string = encrypt_string(clear_string, password)
decrypted_string = decrypt_string(encrypted_string, password)
logger.info(f"clear_string={clear_string} decrypted_string={decrypt_string} password={password}  encrypted_string={encrypted_string}")
logger.debug("Done")
if __name__ == '__main__':
main()

有关源代码的更多详细信息,请访问githubhttps://github.com/redcorjo/pyeasyencrypt

https://pypi.org/project/pyeasyencrypt/

最新更新