如何使用python中的密码加密文本? [英] How to encrypt text with a password in python?

查看:392
本文介绍了如何使用python中的密码加密文本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我想要从用户那里收集一段文字和一则消息,例如 1PWP7a6xgoYx81VZocrDr5okEEcnqKkyDc hello world



然后我想要能够使用文本加密/解密消息,以便我可以将其保存在我的数据库中,而不用担心如果我的网站遭到黑客攻击,数据被暴露,
encrypt('1PWP7a6xgoYx81VZocrDr5okEEcnqKkyDc','hello世界')
decrypt('1PWP7a6xgoYx81VZocrDr5okEEcnqKkyDc',< encrypted_text>)



有没有一个简单的方法来实现这一点与python,请有人提供/引导我一个例子。



也许一个例子,如何创建公共/私人使用种子的密钥对,例如'1PWP7a6xgoYx81VZocrDr5okEEcnqKkyDc'



非常感谢提前:)



编辑:只是要清楚我在找一种以不人道的方式加密我的用户数据的方式,不会使消息模糊。



如果这意味着我必须在飞行中生成一个PGP / GPG pub / pri密钥对通过使用文本 1PWP7a6xgoYx81VZocrDr5okEEcnqKkyDc 作为一个种子,那么这很好,但是做什么方法?

解决方案

以CBC模式正常进行,包括PKCS#7填充:

  import base64 
从Crypto.Cipher导入AES
从Crypto.Hash导入SHA256
从Crypto导入随机

def加密(key,source,encode = True):
key = SHA256.new(key).digest()#在我们的密钥上使用SHA-256获取适当大小的AES密钥
IV = Random.new()。read(AES.block_size)#generate IV
encryptor = AES.new(key,AES.MODE_CBC,IV)
padding = AES.block_size - len(source)%AES.block_size#计算所需填充
source + = bytes([ padding])* padding#Python 2.x:source + = chr(pad din)* padding
data = IV + encryptor.encrypt(source)#在开始时存储IV,并加密
返回base64.b64encode(data).decode(latin-1)if encode else数据

def decrypt(key,source,decode = True):
如果解码:
source = base64.b64decode(source.encode(latin-1))
key = SHA256.new(key).digest()#在我们的密钥上使用SHA-256获取适当大小的AES密钥
IV = source [:AES.block_size]#从开始
decryptor = AES.new(key,AES.MODE_CBC,IV)
data = decryptor.decrypt(source [AES.block_size:])#decrypt
padding = data [-1] #从最终
选择填充值如果data [-padding:]!= bytes([padding])* padding:#Python 2.x:chr(padding)* padding
raise ValueError(无效的填充...)
返回数据[: - padding]#删除填充

它设置为使用字节数据,因此如果要加密字符串或者使用字符串密码,在将它们传递给方法之前,请确保您使用适当的编解码器( encode())。如果您将 encode 参数留给 True encrypt()输出将是base64编码的字符串,而 decrypt() source也应该是base64字符串。



现在如果你测试为:

  my_password = bsecret_AES_key_string_to_encrypt / decrypt_with
my_data = binput_string_to_encrypt / decrypt

print(key:{}format(my_password))
print(data:{}format(my_data))
encrypted = encrypt(my_password,my_data)
print(\\\
enc:{}格式(加密))
decryptpted = decrypt(my_password,encrypted)
print(dec:{}format
print(\\\
data match:{}。format(my_data == decryptpted))
print(\\\
Second round ....)
encrypted = encrypt(my_password ,my_data)
print(\\\
enc:{}格式(加密))
decryptpted = decrypt(my_password,encrypted)
print(dec:{}format解密))
print(\\\
data match:{}。format(my_data == decrypte d))

您的输出将类似于:

  key:b'secret_AES_key_string_to_encrypt / decrypt_with'
data:b'input_string_to_encrypt / decrypt'

enc:7roSO + P / 4eYdyhCbZmraVfc305g5P8VhDBOUDGrXmHw8h5ISsS3aPTGfsTSqn9f5
dec:b'input_string_to_encrypt / decrypt'

数据匹配:True

第二轮...

enc:BQm8FeoPx1H + bztlZJYZH9foI + IKAorCXRsMjbiYQkqLWbGU3NU50OsR + L9Nuqm6
dec:b'input_string_to_encrypt / decrypt'

数据匹配:True

证明相同的密钥和相同的数据每次都会产生不同的密文。



现在,这比ECB好多了,重新使用这个沟通 - 不要!这更多的是解释它应该如何构建,而不是真正地在生产环境中使用,特别是不作为其缺少关键成分 - 消息认证的通信。随便玩,但是你不应该自己加密,所以有很好的协议可以帮助你避免常见的陷阱,你应该使用这些协议。


Surprisingly difficult to find a straight answer to this on Google.

I'm wanting to collect a piece of text and a message from a user such as 1PWP7a6xgoYx81VZocrDr5okEEcnqKkyDc hello world.

Then I want to be able to encrypt/decrypt the message with the text somehow so that I can save it in my database and not worry about the data being exposed if my website gets hacked, encrypt('1PWP7a6xgoYx81VZocrDr5okEEcnqKkyDc', 'hello world') decrypt('1PWP7a6xgoYx81VZocrDr5okEEcnqKkyDc', <encrypted_text>)

Is there a simple way to achieve this with python and please can someone provide/direct me to an example.

Perhaps an example of how to create public/private key pairs using a seed such as '1PWP7a6xgoYx81VZocrDr5okEEcnqKkyDc'?

Many thanks in advance :)

EDIT: Just to be clear I'm looking for a way to encrypt my users data in a determanistic way not obfuscate the message.

If that means I have to generate a PGP/GPG pub/pri key pair on the fly by using the text 1PWP7a6xgoYx81VZocrDr5okEEcnqKkyDc as a seed then that's fine but what's the method to do this?

解决方案

Here's how to do it properly in CBC mode, including PKCS#7 padding:

import base64
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto import Random

def encrypt(key, source, encode=True):
    key = SHA256.new(key).digest()  # use SHA-256 over our key to get a proper-sized AES key
    IV = Random.new().read(AES.block_size)  # generate IV
    encryptor = AES.new(key, AES.MODE_CBC, IV)
    padding = AES.block_size - len(source) % AES.block_size  # calculate needed padding
    source += bytes([padding]) * padding  # Python 2.x: source += chr(padding) * padding
    data = IV + encryptor.encrypt(source)  # store the IV at the beginning and encrypt
    return base64.b64encode(data).decode("latin-1") if encode else data

def decrypt(key, source, decode=True):
    if decode:
        source = base64.b64decode(source.encode("latin-1"))
    key = SHA256.new(key).digest()  # use SHA-256 over our key to get a proper-sized AES key
    IV = source[:AES.block_size]  # extract the IV from the beginning
    decryptor = AES.new(key, AES.MODE_CBC, IV)
    data = decryptor.decrypt(source[AES.block_size:])  # decrypt
    padding = data[-1]  # pick the padding value from the end
    if data[-padding:] != bytes([padding]) * padding:  # Python 2.x: chr(padding) * padding
        raise ValueError("Invalid padding...")
    return data[:-padding]  # remove the padding

It's set to work with bytes data, so if you want to encrypt strings or use string passwords make sure you encode() them with a proper codec before passing them to the methods. If you leave the encode parameter to True the encrypt() output will be base64 encoded string, and decrypt() source should be also base64 string.

Now if you test it as:

my_password = b"secret_AES_key_string_to_encrypt/decrypt_with"
my_data = b"input_string_to_encrypt/decrypt"

print("key:  {}".format(my_password))
print("data: {}".format(my_data))
encrypted = encrypt(my_password, my_data)
print("\nenc:  {}".format(encrypted))
decrypted = decrypt(my_password, encrypted)
print("dec:  {}".format(decrypted))
print("\ndata match: {}".format(my_data == decrypted))
print("\nSecond round....")
encrypted = encrypt(my_password, my_data)
print("\nenc:  {}".format(encrypted))
decrypted = decrypt(my_password, encrypted)
print("dec:  {}".format(decrypted))
print("\ndata match: {}".format(my_data == decrypted))

your output would be similar to:

key:  b'secret_AES_key_string_to_encrypt/decrypt_with'
data: b'input_string_to_encrypt/decrypt'

enc:  7roSO+P/4eYdyhCbZmraVfc305g5P8VhDBOUDGrXmHw8h5ISsS3aPTGfsTSqn9f5
dec:  b'input_string_to_encrypt/decrypt'

data match: True

Second round....

enc:  BQm8FeoPx1H+bztlZJYZH9foI+IKAorCXRsMjbiYQkqLWbGU3NU50OsR+L9Nuqm6
dec:  b'input_string_to_encrypt/decrypt'

data match: True

Proving that same key and same data still produce different ciphertext each time.

Now, this is much better than ECB but... if you're going to use this for communication - don't! This is more to explain how it should be constructed, not really to be used in a production environment and especially not for communication as its missing a crucial ingredient - message authentication. Feel free to play with it, but you should not roll your own crypto, there are well vetted protocols that will help you avoid the common pitfalls and you should use those.

这篇关于如何使用python中的密码加密文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆