【问题标题】:Python 3 - Extract public key from X509 certificate and encrypt with itPython 3 - 从 X509 证书中提取公钥并用它加密
【发布时间】:2014-06-23 03:08:52
【问题描述】:

由于 M2Crypto 库不适用于 Python 3,我正在寻找一种方法来读取 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# 库已经过测试。)它可以工作用于命令行 OpenSSL 生成的证书。

我检查了第二个函数的输出,它与第一个不同,但输出的最后 266 个字节是等效的:

extract_publickey_1(certstr)[-266:] == extract_publickey_2(certstr)[-266:]

返回True

我的问题是,这里发生了什么?有解决办法吗?

【问题讨论】:

  • 如果您发布其中一个会产生错误的证书和一个不会产生错误的证书,那么调查您的问题可能会更容易;可能使用最小的密钥大小。
  • @AntonSamsonov This certificate 有效。 This one 没有。

标签: python ssl encryption cryptography openssl


【解决方案1】:

首先,您必须了解,由于 X.509 证书以 ASN.1 格式编码,因此它表示为各种值的深度和任意嵌套集合 — 嵌套样式和值数据类型可能即使在DER模式下也是任意的。因此,期望一个固定位置和固定形式的字段是非常幼稚的,即。 e.无需进一步嵌套并具有严格的数据类型(尤其是在涉及文本字符串时);更不用说使用“魔法常量”总是是个坏主意。这就是为什么您应该使用专门的函数,例如 get_pubkey()尽可能地而不是尝试自己解析复杂的文档,就像您使用 asn1 类所做的那样。

其次,您必须了解,由于 X.509 规范与算法无关,因此没有“RSA 模数”、“RSA 公共指数”等特定字段。相反,只有一个通用的“公钥”字段具有一组嵌套的子字段——指定算法 OID 及其数字属性。例如,RSA公钥有2个属性:模数n和加密指数e;此外,您的 extract_publickey_2() 函数会添加一个始终为零的属性,我不知道它代表什么。 您的 RSA 实现很可能需要数字参数而不是字节数组或复杂的 ASN.1 值,这就是为什么您可能需要使用 asn1.DerSequence.decode() 或更特定于 RSA 的函数来提取它们的原因.

【讨论】:

  • 我已经澄清了问题的最后一部分。
  • 我也是......有点澄清。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-13
  • 2011-08-12
  • 2017-05-03
  • 2018-08-03
  • 1970-01-01
  • 2012-07-17
  • 2018-01-27
相关资源
最近更新 更多