我有以下 python 代码,用于创建一段 DER 数据“x25519_pubic_der”。
#!/usr/bin/python3
from cryptography.hazmat.primitives.asymmetric import x25519
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
x25519_key = x25519.X25519PrivateKey.generate()
x25519_public_der = x25519_key.public_key().public_bytes(Encoding.DER,
PublicFormat.SubjectPublicKeyInfo)
我尝试使用 C 代码将这段数据解码回其原始二进制位,但不起作用。下面是一个测试程序(假设数据传输正确,长度也正确)。
const unsigned char* ptr = x25519_public_der;
ASN1_OCTET_STRING* octet_string = d2i_ASN1_OCTET_STRING(NULL, &ptr, x25519_public_der_len);
if (!octet_string) {
fprintf(stderr, "Error decoding DER data to binary bytes\n");
return 1;
}
我怀疑 PublicFormat.SubjectPublicKeyInfo 可能会添加一些额外的编码,或者我没有使用正确的 d2i_ 函数(?),只是猜测......
基本上 x25519_public_der 包含 44 个字节,我想使用 C 编程将其恢复为 32 个字节。我认为这个问题可能是相关的,How do I pass a 44 Bytes x25519 public key generated by openssl to CryptoKit which require a key length of 32 Bytes,但我没有足够的背景来在 C 中实现它。
由于原始公钥位于 SPKI/DER X25519 密钥的末尾,因此可以简单地使用最后 32 个字节。
更通用的方法是将 SPKI/DER 密钥导入为
EVP_PKEY
并使用 提取原始密钥EVP_PKEY_get_raw_public_key
,例如从 OpenSSL v3.0 开始(为了简单起见,不进行异常处理):为了完整起见:
OSSL_DECODER_CTX_new_for_pkey()
可用于导入不同类型(第4个参数,例如)和编码(第2个参数,例如或)的公共(第5OSSL_KEYMGMT_SELECT_PUBLIC_KEY
个参数: )和私有(第5个参数: )密钥。 对于私钥,必须用于导出原始密钥。 根据,可以选择不同的数据源。OSSL_KEYMGMT_SELECT_KEYPAIR
"X25519"
"PEM"
"DER"
EVP_PKEY_get_raw_private_key()
OSSL_DECODER_from_...