Python将整数转换为16字节字节

时间:2016-05-19 21:19:05

标签: python cryptography type-conversion data-conversion

我试图在我的代码中使用AES-CTR-128。我使用Python 2.7并使用cryptography模块进行加密。

我需要设置特定的Counter值,例如counter_iv = 112.当我尝试

import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
backend = default_backend()
key = os.urandom(32)
counter_iv = 112
cipher = Cipher(algorithms.AES(key), modes.CTR(counter_iv), backend=backend)
encryptor = cipher.encryptor()
ciphertext = encryptor.update(b"a secret message") + encryptor.finalize()

这给了我一条错误信息:

Traceback (most recent call last):
File "aestest.py", line 14, in <module>
  cipher = Cipher(algorithms.AES(key), modes.CTR(counter_iv), backend=backend)
File "/usr/local/lib/python2.7/dist-packages/cryptography/hazmat/primitives/ciphers/modes.py", line 139, in __init__
  raise TypeError("nonce must be bytes")
TypeError: nonce must be bytes

我认为它告诉我counter_iv应该是一个16字节的字符串。

我的问题是如何将整数或长整数转换为16字节的字符串?

此外,有没有办法将整数转换为任何长度的字符串?谢谢你的帮助。

2 个答案:

答案 0 :(得分:3)

首先,您是否有充分的理由使用低级有害物质而不是更高级别的API?此级别仅用于特殊用途的高级API。

接下来,您通过编写modes.CTR(counter_iv)来误导任何其他读者,因为计数器模式根据其{不使用初始化向量而是使用 nonce {3}}。你得到的错误是正常的,因为doc声明nonce应该是一个与密码块相同大小的字节串 ,因此对于AES,它必须是128位或16字节。

顺便说一句,该文件还指出,不应该重用一个随机数

  

......永远不要重复使用给定密钥的随机数是至关重要的。任何使用相同密钥的nonce的重用都会危及使用该密钥加密的每条消息的安全性。

Nayuki的答案解释了如何从int构建一个16字节的字符串,但如果使用低级有害物质

,请确保正确使用加密技术

答案 1 :(得分:2)

在Python 2中,您可以将整数转换为小端的字节串,如下所示:

counter_iv = 112  # This can be a pretty big number
iv_bytes = "".join(chr((counter_iv >> (i * 8)) & 0xFF) for i in range(16))

扩展代码以解释:

counter_iv = 112  # Can be from 0 to 3.40e38
temp = []  # Will be an array of bytes
for i in range(16):
    # Get the i'th byte counting from the least significant end
    b = (counter_iv >> (i * 8)) & 0xFF
    temp.append(b)
# For example, temp == [0x70, 0x00, ... 0x00]

# Will be an array of 1-character strings
temp2 = [chr(b) for b in temp]
# For example, temp2 == ['\x70', '\x00', ..., '\x00']

# Concatenate all the above together
iv_bytes = "".join(temp2)
# For example, iv_bytes == '\0x70\0x00...\0x00'