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

sum*_*mat 3 python twisted pyopenssl public-key

我目前正在尝试编写一个python服务器脚本,该脚本应根据其公钥对当前客户端进行身份验证.因为我正在使用扭曲,扭曲的文档中例子让我开始.

虽然我可以使用示例代码生成密钥,连接和通信,但我还没有找到一种方法来以可用的格式获取客户端的公钥.在这个stackexchange问​​题中,有人从OpenSSL.crypto.PKey对象中提取公钥但不能将其转换为可读格式.因为在我可以通过方法或通过我的协议的任何方法访问PKeyx509证书的对象,这将是一个很好的方法.(不接受)答案建议尝试.不幸的是,这并没有真正产生预期的结果:虽然可以通过简单的文本替换功能修复和答案,但是base64字符串似乎与公钥不匹配.我已经提取了这里提到的公钥.它与函数的结果不匹配.verifyCallbackself.transport.getPeerCertificate()crypto.dump_privatekey(PKey)BEGIN PRIVATE KEYBEGIN PRIVATE KEYopenssl rsa -in client.key -pubout > client.pubdump_privatekey

虽然在启动板上仍存在OpenSSL的漏洞,但尚未修复.据报道,19个月前,有一些最近(2012年10月)的活动,我没有希望在回购中快速修复.

您是否有任何其他想法如何以与client.pub我上面提到的文件相当的格式获取公钥?也许存在扭曲或OpenSSL连接特定对象来保存此信息.请注意,我必须将公钥存储在协议对象中,以便以后可以访问它.

为什么没有接受答案?

由JF Sebastian主持的M2Crypto

对不起,我没想到我无法将证书与连接关联起来.我已经添加了必须将公钥存储在协议实例中的要求.因此,使用JF Sebastian建议peerX509.as_pem()postConnectionCheck函数内部不起作用.此外,至少在python-m2crypto的0.21.1-2ubuntu3版本中,我必须调用peerX509.get_rsa().as_pem()才能获得正确的公钥.使用peerX509.as_pem(None)(因为peerX509.as_pem()仍然需要密码)会产生与PyOpenSSL完全相同的输出crypto.dump_privatekey(PKey).也许有一个错误.

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

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)
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这会使用一些我想要阻止的内部类.我犹豫提交一个小补丁这将增加一个getCert方法将TLSProtocolWrapper在M2Crypto.SSL.TwistedProtocolWrapper类.即使它被上游接受,它也会破坏我的脚本与m2crypto最简洁的版本之间的兼容性.你会怎么做?

外部OpenSSL由我打电话

嗯,它是一个基于外部系统命令的丑陋的解决方法,在我看来比访问非公共属性更糟糕.

小智 6

以前的一些答案产生(显然是?)正在工作的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)
Run Code Online (Sandbox Code Playgroud)

  • 您介意解释一下它如何工作吗@ jessica-gadling (2认同)