翼度科技»论坛 编程开发 python 查看内容

Python加密库 Crypto.Cipher包中 ChaCha20 介绍

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
该软件包包含用于保护机密性的算法 的数据。Crypto.Cipher
有三种类型的加密算法:

  • 对称密码:所有各方都使用相同的密钥 解密和加密数据。 对称密码通常非常快,可以处理 非常大量的数据。
  • 非对称密码:发送方和接收方使用不同的密钥。 发送方使用公钥(非机密)加密,而接收方 使用私钥(机密)解密。 非对称密码通常非常慢,可以处理 只有非常小的有效载荷。示例:PKCS#1 OAEP (RSA)。
  • 混合密码:上述两种类型的密码可以组合使用 在继承两者优点的结构中。 非对称密码用于保护短期 对称键, 和对称密码(在该密钥下)加密 实际消息。
对称密码
有两种类型的对称密码:

  • 流密码:最自然的密码类型: 它们一次加密一个字节的数据。 参见ChaCha20和XChaCha20和Salsa20
  • 分组密码:只能以固定数量操作的密码 的数据。最重要的分组密码是AES,它具有 块大小为 128 位(16 字节)。
    通常,分组密码通常仅与 一种操作模式,允许加密 可变数量的数据。某些模式(如点击率)可以有效地转动 将分组密码转换为流密码。
广泛的共识是,密码提供 只有机密性,没有任何形式的身份验证,是不可取的。 相反,基元已被定义为集成对称加密和 身份验证 (MAC)。例如:
ChaCha20 和 XChaCha20

ChaCha20是由Daniel J. Bernstein设计的流密码。 密钥长度为 256 位(32 字节)。 密码需要随机数,不得重复使用 跨使用同一密钥执行的加密。
有三种变体,由随机数的长度定义:
随机数长度描述最大数据如果随机随机数和相同的键8 字节(默认)由伯恩斯坦设计的原始ChaCha20。无限制最多 200 000 条消息12 字节RFC7539 中定义的 TLS ChaCha20。256 千兆字节最多 130 亿条消息24 字节XChaCha20,仍处于草稿阶段。256 千兆字节无限制
  1. 这是ChaCha20(Bernstein的版本)如何加密数据的一个例子:
  2. import json
  3. from base64 import b64encode
  4. from Crypto.Cipher import ChaCha20
  5. from Crypto.Random import get_random_bytes
  6. plaintext = b'Attack at dawn'
  7. key = get_random_bytes(32)
  8. cipher = ChaCha20.new(key=key)
  9. ciphertext = cipher.encrypt(plaintext)
  10. nonce = b64encode(cipher.nonce).decode('utf-8')
  11. ct = b64encode(ciphertext).decode('utf-8')
  12. result = json.dumps({'nonce':nonce, 'ciphertext':ct})
  13. print(result)
  14. {"nonce": "IZScZh28fDo=", "ciphertext": "ZatgU1f30WDHriaN8ts="}
  15. 这就是您解密它的方式:
  16. import json
  17. from base64 import b64decode
  18. from Crypto.Cipher import ChaCha20
  19. # We assume that the key was somehow securely shared
  20. try:
  21.     b64 = json.loads(json_input)
  22.     nonce = b64decode(b64['nonce'])
  23.     ciphertext = b64decode(b64['ciphertext'])
  24.     cipher = ChaCha20.new(key=key, nonce=nonce)
  25.     plaintext = cipher.decrypt(ciphertext)
  26.    print("The message was " + plaintext)
  27. except (ValueError, KeyError):
  28.     print("Incorrect decryption")
  29. 为了拥有符合 RFC7539 标准的 ChaCha20 密码, 您需要显式生成 96 位(12 字节)参数并将其传递给:noncenew()
  30. nonce_rfc7539 = get_random_bytes(12)
  31. cipher = ChaCha20.new(key=key, nonce=nonce_rfc7539)
复制代码
 
警告
ChaCha20不保证您解密的数据的真实性! 换句话说,攻击者可能会操纵传输中的数据。 为了防止这种情况,您还必须使用消息身份验证 用于验证密文的代码(如 HMAC) (加密然后 Mac)。或者,您可以使用ChaCha20_Poly1305
.classCrypto.Cipher.ChaCha20.ChaCha20Cipher(随机数)ChaCha20(或XChaCha20)密码对象。 不要直接创建它。请改用 new()。
变量:随机数 (字节)– 长度为 8、12 或 24 字节的随机数decrypt(密文输出=无)解密一段数据。
参数:密文 (字节/字节数组/内存视图)– 要解密的数据,任何大小。关键字参数: 输出 (字节/字节数组/内存视图)– 明文的位置 被写到。如果为 ,则返回明文。None返回:如果是,则明文返回为 。 否则。outputNonebytesNoneencrypt(纯文本输出 = 无)加密一段数据。
参数:明文 (字节/字节数组/内存视图)– 要加密的数据,任何大小。关键字参数: 输出 (字节/字节数组/内存视图)– 密文的位置 被写到。如果为 ,则返回密文。None返回:如果是,则密文返回为 。 否则。outputNonebytesNoneseek(位置)查找密钥流中的某个位置。
参数:位置 (整数)– 密钥流中的绝对位置,以字节为单位。Crypto.Cipher.ChaCha20.new(**夸格斯)创建新的 ChaCha20 或 XChaCha20 密码
关键字参数: 

  • key (bytes/bytearray/memoryview) – 要使用的密钥。 它必须为 32 字节长。
  • nonce(bytes/bytearray/memoryview) –强制值 不得重用于任何其他加密 使用此密钥完成。
    对于 ChaCha20,它必须为 8 或 12 个字节。
    对于 XChaCha20,它必须为 24 字节长。
    如果未提供,将随机生成 8 个字节 (您可以在属性中找到它们)。nonce
返回:一个 Crypto.Cipher.ChaCha20.ChaCha20Cipher 对象
转载:ChaCha20 和 XChaCha20 — PyCryptodome 3.17.0 文档
ChaCha20-Poly1305 和 XChaCha20-Poly1305

ChaCha20-Poly1305 是具有关联数据 (AEAD) 的经过身份验证的密码。 它与一个 32 字节的密钥和一个随机数一起工作 绝不能在同一密钥下执行的加密中重复使用。 密码生成一个 16 字节标记,接收方必须使用该标记来验证消息。
该算法有三种变体,由随机数的长度定义:
随机数长度描述最大明文数如果随机随机数和相同的键8 字节基于伯恩斯坦的原始ChaCha20。无限制最多 200 000 条消息12 字节(默认)在 TLS 中使用并在 RFC7539 中指定的版本。256 千兆字节最多 130 亿条消息24 字节XChaCha20-Poly1305,仍处于草稿阶段。256 千兆字节无限制密码的 API 及其有限状态机与分组密码的现代操作模式相同。
通过调用 Crypto.Cipher.ChaCha20_Poly1305.new() 创建新密码。
  1. 以下是 ChaCha20-Poly1305(TLS 版本)如何加密和验证数据的示例:
  2. import json
  3. from base64 import b64encode
  4. from Crypto.Cipher import ChaCha20_Poly1305
  5. from Crypto.Random import get_random_bytes
  6. header = b"header"
  7. plaintext = b'Attack at dawn'
  8. key = get_random_bytes(32)
  9. cipher = ChaCha20_Poly1305.new(key=key)
  10. cipher.update(header)
  11. ciphertext, tag = cipher.encrypt_and_digest(plaintext)
  12. jk = [ 'nonce', 'header', 'ciphertext', 'tag' ]
  13. jv = [ b64encode(x).decode('utf-8') for x in (cipher.nonce, header, ciphertext, tag) ]
  14. result = json.dumps(dict(zip(jk, jv)))
  15. print(result)
  16. {"nonce": "4EE/9uqhoZ3mQXmm", "header": "aGVhZGVy", "ciphertext": "Wmmo4Vzn+eS3tUPv2a8=", "tag": "/FgVbM8qhzssPRY80T0iVA=="}
  17. 在上面的示例中,会自动创建一个 96 位(12 字节)随机数。 可以将其作为对象中的成员进行访问。noncecipher
  18. 这是您解密数据并检查其真实性的方式:
  19. import json
  20. from base64 import b64decode
  21. from Crypto.Cipher import ChaCha20_Poly1305
  22. # We assume that the key was securely shared beforehand
  23. try:
  24.      b64 = json.loads(json_input)
  25.      jk = [ 'nonce', 'header', 'ciphertext', 'tag' ]
  26.     jv = {k:b64decode(b64[k]) for k in jk}
  27.     cipher = ChaCha20_Poly1305.new(key=key, nonce=jv['nonce'])
  28.     cipher.update(jv['header'])
  29.     plaintext = cipher.decrypt_and_verify(jv['ciphertext'], jv['tag'])
  30.     print("The message was: " + plaintext)
  31. except (ValueError, KeyError):
  32.     print("Incorrect decryption")
复制代码
 
.classCrypto.Cipher.ChaCha20_Poly1305.ChaCha20Poly1305Cipher(随机数)ChaCha20-Poly1305 和 XChaCha20-Poly1305 密码对象。 不要直接创建它。请改用 new()。
变量:随机数 (字节字符串)– 长度为 8、12 或 24 字节的随机数decrypt(密文输出=无)解密一段数据。
参数:密文 (字节/字节数组/内存视图)– 要解密的数据,任何大小。关键字参数: 输出 (字节/字节数组/内存视图)– 明文的位置 被写到。如果为 ,则返回明文。None返回:如果是,则明文返回为 。 否则。outputNonebytesNonedecrypt_and_verify(密文received_mac_tag)一步执行 decrypt() 和 verify()。
参数:

  • 密文(字节/字节数组/内存视图)– 要解密的数据片段。
  • received_mac_tag(字节)— 这是从发送方接收的 16 字节二进制 MAC。
返回:解密的数据(作为bytes)
提高:值错误 – 如果 MAC 不匹配。邮件已被篡改 或者密钥不正确。
digest()计算二进制身份验证标记 (MAC)。
返回:MAC 标记,作为 16 .bytesencrypt(纯文本输出 = 无)加密一段数据。
参数:明文 (字节/字节数组/内存视图)– 要加密的数据,任何大小。关键字参数: 输出 (字节/字节数组/内存视图)– 密文的位置 被写到。如果为 ,则返回密文。None返回:如果是,则密文返回为 。 否则。outputNonebytesNoneencrypt_and_digest(明文)在一个步骤中执行 encrypt() 和 digest()。
参数:明文 (字节/字节数组/内存视图)– 要加密的数据,任何大小。返回:包含两个对象的元组:bytes

  • 密文,长度与明文相同
  • 16 字节 MAC 标签
hexdigest()计算可打印的身份验证标记 (MAC)。
此方法类似于摘要()。
返回:MAC 标记,作为十六进制字符串。hexverify(hex_mac_tag)验证可打印的身份验证标记 (MAC)。
此方法类似于 verify()。
参数:hex_mac_tag (字符串)– 这是可打印的 MAC。提高值错误: 如果 MAC 不匹配。邮件已被篡改 或者密钥不正确。update(数据)保护关联的数据。
关联数据(也称为其他经过身份验证的数据 - AAD) 是必须保持清晰的信息部分,而 仍然允许接收器验证其完整性。 数据包标头就是一个例子。
关联的数据(可能拆分为多个段)为 在调用 decrypt() 或 encrypt() 之前输入到 update() 中。 如果没有关联的数据,则不调用 update()。
参数:assoc_data (字节/字节数组/内存视图)– 一段关联数据。它的大小没有限制。verify(received_mac_tag)验证二进制身份验证标记 (MAC)。
接收方在最后调用此方法, 检查相关数据(如果有)和解密 消息有效。
参数:received_mac_tag (字节/字节数组/内存视图)– 这是从发送方收到的 16 字节二进制 MAC。提高值错误: 如果 MAC 不匹配。邮件已被篡改 或者密钥不正确。Crypto.Cipher.ChaCha20_Poly1305.new(**夸格斯)创建新的 ChaCha20-Poly1305 或 XChaCha20-Poly1305 AEAD 密码。
关键字参数: 

  • key – 要使用的密钥。它必须为 32 字节长。
  • 随机数 –不得重用于任何其他加密的值 使用此密钥完成。
    对于 ChaCha20-Poly1305,它的长度必须为 8 或 12 个字节。
    对于 XChaCha20-Poly1305,它必须为 24 字节长。
    如果未提供,将随机生成 12 个 (您可以在属性中找到它们)。bytesnonce
返回:一个对象Crypto.Cipher.ChaCha20.ChaCha20Poly1305Cipher

来源:https://www.cnblogs.com/liang715200/p/17191141.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具