正在从 Python 中的十六进制加载 Public 密钥(DER 格式)

Loading Public Key (DER Format) from Hex in Python

我有一个public关键原始数据(从机器可读旅行证件的NFC芯片中提取。)但是我想在云端和内部IC芯片上执行主动认证。

下面的代码片段显示了 python 的 cryptography 库的加载实现。

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_der_public_key
_pub_key="6F81E03081DD300...."
pub_key_bytes = bytes.fromhex(_pub_key)
print(pub_key_bytes)
load_der_public_key(data = pub_key_bytes,backend=default_backend())

哪个会抛出错误;

ValueError: Could not deserialize key data.

对应的就是这个(在他们documentation.)

Raised when an operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception such as IndexError

还有; 我知道 public 密钥的格式正确(至少在开头),因为第一个字节是 0/,这是 DER 格式所需的魔术字节。

我也知道 public 密钥的长度为 454 个字符,而 RSA public 密钥的长度为 256 个字节(等于 512 个十六进制字符。)

我尝试添加右填充以完成 512 个字符的密钥:

_pub_key = _pub_key+f"{'0'*(512-len(_pub_key))}"

这也导致了同样的错误。

PS: 我知道密钥是有效的,因为在微处理器中成功完成了身份验证(签名+验证)。

Link to My Public Key

您必须删除数据的前三个字节,即 0x6F81E0。其余的,即 0x3081DD...010001 是实际密钥(DER 编码,X.509/SPKI 格式,1536 位)。您可以使用 ASN.1 解析器进行检查,例如https://lapo.it/asn1js/.


为了完整性:RSA 密钥的大小对应于模数的大小。出于安全原因,今天的 RSA 密钥大小至少应为 2048 位。除了模数之外,RSA 密钥还有其他参数,例如对于 public 密钥,public 指数。
RSA 密钥可以封装为不同的格式,例如发布的密钥是 X.509/SPKI 格式的 ASN.1/DER 编码 public 密钥。由于附加参数和 format-dependent 元数据,这样的密钥大于模数的大小。
ASN.1/DER 编码的密钥通常不以 0x00 开头。但是,ASN.1/DER 编码规则可能导致数据中出现 0x00 值(当然,关键参数本身也可以包含 0x00 值)。