Python pycryptodome类库使用学习总结

打印 上一主题 下一主题

主题 508|帖子 508|积分 1524

AES数据加解密

以下代码天生一个新的AES-128密钥,并将一段数据加密到一个文件中。我们使用 CTR 模式(这是一种 经典利用模式, 简单但不再保举)。
仅使用CTR,接收者无法检测到密文(即加密数据)在传输过程中是否被修改。为了应对这种风险,例中还附加了一个MAC身份验证标签(采用SHA256模式的HMAC),该标签由第二个密钥制成。
  1. # -*- coding:utf-8 -*-
  2. from Crypto.Cipher import AES
  3. from Crypto.Hash import HMAC, SHA256
  4. from Crypto.Random import get_random_bytes
  5. data = 'secret data to transmit'.encode()
  6. aes_key = get_random_bytes(16) # 返回一个包含适合加密使用的随机字节的字节对象
  7. print('aes_key: ', aes_key) # aes_key:  b'\xf6Ke|/M\x93tv\n\xec\x1ej\xb4k\xab'
  8. cipher = AES.new(aes_key, AES.MODE_CTR) # 创建一个 AES cipher
  9. ciphertext = cipher.encrypt(data) # 加密数据,返回字节对象
  10. hmac_key = get_random_bytes(16)
  11. print('hmac_key: ', hmac_key) # hmac_key:  b'hU\xe6O\x8a\xc5\xa4g\xf3"\xc1K,f\x96\xdb'
  12. hmac = HMAC.new(hmac_key, digestmod=SHA256)
  13. tag = hmac.update(cipher.nonce + ciphertext).digest()
  14. with open("encrypted.bin", "wb") as f:
  15.     f.write(tag)
  16.     f.write(cipher.nonce)
  17.     f.write(ciphertext)
  18. # 与接收者安全共享 aes_key和hmc_key
  19. # encrypted.bin 可通过非安全信道传输
复制代码
最后,接收者可以安全地加载回数据(假如他们知道这两个密钥(aes_key和hmc_key的话))。请注意,当检测到篡改时,代码会抛出ValueError异常。
  1. import sys
  2. from Crypto.Cipher import AES
  3. from Crypto.Hash import HMAC, SHA256
  4. aes_key = b'\xf6Ke|/M\x93tv\n\xec\x1ej\xb4k\xab'
  5. hmac_key = b'hU\xe6O\x8a\xc5\xa4g\xf3"\xc1K,f\x96\xdb'
  6. with open("encrypted.bin", "rb") as f:
  7.     tag = f.read(32)
  8.     nonce = f.read(8)
  9.     ciphertext = f.read()
  10. try:
  11.     hmac = HMAC.new(hmac_key, digestmod=SHA256)
  12.     tag = hmac.update(nonce + ciphertext).verify(tag)
  13. except ValueError:
  14.     print("The message was modified!")
  15.     sys.exit(1)
  16. cipher = AES.new(aes_key, AES.MODE_CTR, nonce=nonce)
  17. message = cipher.decrypt(ciphertext) # 解密数据,返回字节对象
  18. print("Message:", message.decode())  # 输出:Message: secret data to transmit
复制代码
一步完成数据加密和验证

上一节中的代码包含三个微妙但重要的设计决策:cipher的nonce经过验证,验证在加密后实行,且加密和验证使用两个不相关的密钥。安全地组合加密原语并不容易,因此已经创建了更现代的加密cipher模式,OCB mode (查阅其它 经过身份验证的加密模式EAX, GCM, CCM, SIV)。
  1. # -*- coding:utf-8 -*-
  2. from Crypto.Cipher import AES
  3. from Crypto.Random import get_random_bytes
  4. data = 'secret data to transmit'.encode()
  5. aes_key = get_random_bytes(16)
  6. print('aes_key: ', aes_key) # aes_key:  b'p.\xb7iD\x8a\xb6\xdc\x1e\x80E\xf4k:\xb4q'
  7. cipher = AES.new(aes_key, AES.MODE_OCB)
  8. ciphertext, tag = cipher.encrypt_and_digest(data)
  9. assert len(cipher.nonce) == 15
  10. with open("encrypted.bin", "wb") as f:
  11.     f.write(tag)
  12.     f.write(cipher.nonce)
  13.     f.write(ciphertext)
  14. # 与接收者安全共享 aes_key
  15. # encrypted.bin 可通过非安全信道传输
复制代码
数据解密
  1. # -*- coding:utf-8 -*-
  2. from Crypto.Cipher import AES
  3. aes_key = b'p.\xb7iD\x8a\xb6\xdc\x1e\x80E\xf4k:\xb4q'
  4. with open("encrypted.bin", "rb") as f:
  5.     tag = f.read(16)
  6.     nonce = f.read(15)
  7.     ciphertext = f.read()
  8. cipher = AES.new(aes_key, AES.MODE_OCB, nonce=nonce)
  9. try:
  10.     message = cipher.decrypt_and_verify(ciphertext, tag)
  11. except ValueError:
  12.     print("The message was modified!")
  13.     exit(1)
  14. print("Message:", message.decode())
复制代码
RSA数据加解密

天生RSA秘钥

以下代码天生一个新的RSA密钥对(secret),并将其保存到一个受密码保护的文件中。使用 脚本 密钥推导函数,以制止字典攻击。最后,代码以ASCII/PEM格式打印RSA公钥:
  1. from Crypto.PublicKey import RSA
  2. secret_code = "Unguessable"
  3. key = RSA.generate(2048)
  4. encrypted_key = key.export_key(passphrase=secret_code, pkcs=8,
  5.                               protection="scryptAndAES128-CBC",
  6.                               prot_params={'iteration_count':131072})
  7. with open("rsa_key.bin", "wb") as f:
  8.     f.write(encrypted_key)
  9. print(key.publickey().export_key())
复制代码
以下代码读取私钥RSA,然后再次打印公钥
  1. from Crypto.PublicKey import RSA
  2. secret_code = "Unguessable"
  3. encoded_key = open("rsa_key.bin", "rb").read()
  4. key = RSA.import_key(encoded_key, passphrase=secret_code)
  5. print(key.publickey().export_key())
复制代码
天生公钥和私钥

以下代码天生存储在receiver.pem中的公钥和存储在private.pem中的私钥。这些文件将在下面的示例中使用。每次天生不同的公钥和私钥对。
  1. from Crypto.PublicKey import RSA
  2. key = RSA.generate(2048)
  3. private_key = key.export_key()
  4. with open("private.pem", "wb") as f:
  5.     f.write(private_key)
  6. public_key = key.publickey().export_key()
  7. with open("receiver.pem", "wb") as f:
  8.     f.write(public_key)
复制代码
使用RSA加解密数据

以下代码为我们拥有RSA公钥的接收者加密了一段数据。RSA公钥存储在一个名为receiver.pem的文件中。
为了能够加密任意数量的数据,使用混合加密方案。为AES会话密钥的非对称加密,使用RSA及PKCS1OAEP 。然后,会话密钥可用于加密所有实际数据。
与第一个示例一样,使用EAX模式来检测未经授权的修改
  1. from Crypto.PublicKey import RSA
  2. from Crypto.Random import get_random_bytes
  3. from Crypto.Cipher import AES, PKCS1_OAEP
  4. data = "I met aliens in UFO. Here is the map.".encode("utf-8")
  5. recipient_key = RSA.import_key(open("receiver.pem").read())
  6. session_key = get_random_bytes(16)
  7. # 使用公钥加密会话key
  8. cipher_rsa = PKCS1_OAEP.new(recipient_key)
  9. enc_session_key = cipher_rsa.encrypt(session_key)
  10. # 使用AES会话key加密数据
  11. cipher_aes = AES.new(session_key, AES.MODE_EAX)
  12. ciphertext, tag = cipher_aes.encrypt_and_digest(data)
  13. with open("encrypted_data.bin", "wb") as f:
  14.     f.write(enc_session_key)
  15.     f.write(cipher_aes.nonce)
  16.     f.write(tag)
  17.     f.write(ciphertext)
复制代码
接收方拥有RSA私钥。将首先使用它解密会话密钥,然后解密文件的其余部门::
  1. from Crypto.PublicKey import RSA
  2. from Crypto.Cipher import AES, PKCS1_OAEP
  3. private_key = RSA.import_key(open("private.pem").read())
  4. with open("encrypted_data.bin", "rb") as f:
  5.     enc_session_key = f.read(private_key.size_in_bytes())
  6.     nonce = f.read(16)
  7.     tag = f.read(16)
  8.     ciphertext = f.read()
  9. # 使用私钥解密会话key
  10. cipher_rsa = PKCS1_OAEP.new(private_key)
  11. session_key = cipher_rsa.decrypt(enc_session_key)
  12. # 使用AES会话key解密数据
  13. cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
  14. data = cipher_aes.decrypt_and_verify(ciphertext, tag)
  15. print(data.decode("utf-8"))
复制代码
参考连接

https://www.pycryptodome.org/src/examples

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

宝塔山

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表