python - 使用 pyOpenSSL 从证书或其他连接信息中提取公钥

标签 python twisted public-key pyopenssl

我目前正在尝试编写一个 python 服务器脚本,该脚本应根据其公钥对当前客户端进行身份验证。由于我使用的是扭曲的,example in the twisted documenteation让我开始了。

虽然我可以使用示例代码生成 key 、连接和通信,但我还没有找到以可用格式获取客户端公钥的方法。在 this stackexchange question有人从 OpenSSL.crypto.PKey 中提取公钥对象,但不能将其转换为可读格式。因为我可以访问 PKey verifyCallback 中 x509 证书的对象方法或通过 self.transport.getPeerCertificate()从我的协议(protocol)的任何方法来看,这将是一个很好的方法。 (未接受)答案建议尝试 crypto.dump_privatekey(PKey) .不幸的是,这并没有真正产生预期的结果: 而 BEGIN PRIVATE KEYBEGIN PRIVATE KEY在答案中可以通过简单的文本替换功能修复,base64 字符串似乎与公钥不匹配。我用 openssl rsa -in client.key -pubout > client.pub 提取了公钥如前所述here .它与 dump_privatekey 的结果不匹配功能。

虽然还有一个 open bug towards OpenSSL on launchpad ,目前还没有确定。它是 19 个月前报道的,最近(2012 年 10 月)有一些事件,我不希望在 repos 中快速修复。

您是否有任何其他想法可以让我以类似于 client.pub 的格式获得公钥?我上面提到的文件?可能有一个扭曲的或 OpenSSL 连接特定对象保存此信息。请注意,我必须将公钥存储在协议(protocol)对象中,以便我以后可以访问它。

为什么不接受答案?

J.F. Sebastian 的 M2Crypto

抱歉,我没有想到无法将证书与连接相关联的可能性。我添加了必须将公钥存储在协议(protocol)实例中的要求。因此,使用 peerX509.as_pem()postConnectionCheck里面J.F. 塞巴斯蒂安建议的功能不起作用。此外,至少在 python-m2crypto 的 0.21.1-2ubuntu3 版本中我必须调用 peerX509.get_rsa().as_pem()获得正确的公钥。使用 peerX509.as_pem(None) (因为 peerX509.as_pem() 仍然需要密码)产生与 crypto.dump_privatekey(PKey) 完全相同的输出在 PyOpenSSL 中。可能有错误。

除此之外,答案还向我展示了使用以下 Echo 编写另一种解决方法的可能方法协议(protocol)类:

class Echo(Protocol):
    def dataReceived(self, data):
        """As soon as any data is received, write it back."""
        if self.transport.checked and not self.pubkeyStored:
            self.pubkeyStored = True
            x509 = m2.ssl_get_peer_cert(self.transport.ssl._ptr())
            if x509 is not None:
                x509 = X509.X509(x509, 1)
                pk = x509.get_pubkey()
                self.pubkey = pk.get_rsa().as_pem()
                print pk.as_pem(None)
            print self.pubkey
        self.transport.write(data)

如您所见,它使用了一些我想阻止的内部类。我正在犹豫提交一个小补丁,它会添加一个 getCert TLSProtocolWrapper 的方法M2Crypto.SSL.TwistedProtocolWrapper 中的类。即使它被上游接受,它也会破坏我的脚本与除最先进的 m2crypto 版本之外的任何版本的兼容性。你会怎么做?

由我调用外部 OpenSSL

好吧,这是一个基于外部系统命令的丑陋解决方法,在我看来,它甚至比访问非公共(public)属性更糟糕。

最佳答案

以前的一些答案产生(显然?)工作 PEM 公钥文件,但据我所试,它们都没有产生与“openssl rsa -pubout -in priv.key”相同的输出。这对我的测试套件非常重要,在查看 (0.15.1) PyOpenSSL 代码后,这适用于标准 PKey 对象和由 x509.get_pubkey() 方法创建的仅限公钥的 PKey 对象:

from OpenSSL import crypto
from OpenSSL._util import lib as cryptolib


def pem_publickey(pkey):
    """ Format a public key as a PEM """
    bio = crypto._new_mem_buf()
    cryptolib.PEM_write_bio_PUBKEY(bio, pkey._pkey)
    return crypto._bio_to_string(bio)


key = crypto.PKey()
key.generate_key(crypto.TYPE_RSA, 2048)
print pem_publickey(key)

关于python - 使用 pyOpenSSL 从证书或其他连接信息中提取公钥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13845470/

相关文章:

python - Selenium click 可以与标签一起使用吗?

django - Twisted 服务器作为 Django 的生产服务器(+ django-wsgi)

python - 扭曲为 python : Is there an ETA or beta for python v3?

java - RSA。 Java 加密 .NET 解密

java - BCECPublicKey 到指纹

python - Tkinter 按钮向消息添加行

python - cx_Oracle查询结果到嵌套字典

digital-signature - 公钥如何验证签名?

python - 是否可以在没有标准库的情况下嵌入 python?

python - 高速公路 WAMP 服务器的命令式客户端?