由于python3没有M2Crypto库,所以我正在寻找一种方法来读入X509证书,从中提取公钥并将其用于RSA加密。在
我目前有以下两个职能:
from ssl import PEM_cert_to_DER_cert # standard library
from Crypto.Util import asn1 # http://pycrypto.org
from OpenSSL.crypto import * # https://pythonhosted.org/pyOpenSSL/
def extract_publickey_1(certstr):
""" from http://stackoverflow.com/questions/12911373 """
der = PEM_cert_to_DER_cert(certstr)
cert = asn1.DerSequence()
cert.decode(der)
tbs = asn1.DerSequence()
tbs.decode(cert[0])
return tbs[6]
def extract_publickey_2(certstr):
return dump_privatekey(FILETYPE_ASN1,
load_certificate(FILETYPE_PEM, certstr).get_pubkey())
第一个函数为某些证书引发IndexError
,特别是那些由命令行OpenSSL生成的证书,而是一些加密库(python和c#libs已测试)生成的证书,它适用于命令行OpenSSL生成的证书。在
我检查了第二个函数的输出,它与第一个函数不相同,但输出的最后266字节是等效的:
^{pr2}$返回True
。在
我的问题是,这是怎么回事?有解决办法吗?在
首先,您必须了解,因为X.509证书是以ASN.1格式编码的,它被表示为各种值的深度和任意嵌套集合,并且嵌套样式和值数据类型即使在DER模式下也可能是任意的。因此,期望字段在固定位置以固定形式出现是非常幼稚的,即没有进一步的嵌套和严格的数据类型(尤其是当涉及到文本字符串时);更不用说使用“magic constants”总是一个坏主意。这就是为什么您应该尽可能使用专用函数如
get_pubkey()
,而不是像使用asn1
类那样尝试自己解析一个复杂的文档。在其次,您必须了解,因为X.509规范与算法无关,因此没有“RSA模数”、“RSA公共指数”等特定字段。相反,只有一个通用的“公钥”字段有一组嵌套的子字段-指定算法OID及其数值属性。例如,RSA公钥有两个属性:模数
n
和加密指数e
;此外,您的extract_publickey_2()
函数在属性前面加了一个始终为零的属性,我不知道它代表什么。您的RSA实现很可能需要数字参数,而不是字节数组或复杂的ASN.1值,这就是为什么您可能需要使用asn1.DerSequence.decode()
或更具体的RSA函数来提取它们。在相关问题 更多 >
编程相关推荐