Python:使用.Cer文件打开以获取公钥然后执行验证

时间:2014-12-01 13:21:17

标签: python cryptography pycrypto

我有一个包含公钥的.cer文件。我需要使用此文件来验证由相应私钥签名的签名。 我有签名和公钥。我需要验证签名。 我的结果是假的。 以下是代码:

def verify_sign(public_key_loc, signature, data):
    '''
    Verifies with a public key from whom the data came that it was indeed
    signed by their private key
    param: public_key_loc Path to public key
    param: signature String signature to be verified
    return: Boolean. True if the signature is valid; False otherwise.
    '''
    #pdb.set_trace()
    from Crypto.PublicKey import RSA
    from Crypto.Signature import PKCS1_v1_5
    from Crypto.Hash import SHA256
    from base64 import b64decode
    try:
        pub_key = open(public_key_loc, "r").read()
        rsakey = RSA.importKey(pub_key)
        signer = PKCS1_v1_5.new(rsakey)
        digest = SHA256.new()
        # Assumes the data is base64 encoded to begin with
        digest.update(b64decode(data))
        if signer.verify(digest, b64decode(signature)):
            return True
        return False 
    except Exception as e:
        print e

我尝试在这里使用方法将.cer文件转换为.pem。 How do I use a X509 certificate with PyCrypto?

此处使用的方法是否正确?或者python有更好的库。因为据我所知,python不支持X.509Certificate。 承担我的英语。 感谢任何帮助。

感谢。

修改

截至目前,我正在尝试使用Pycrypto。 我是否需要在同一个pycrypto中使用任何其他库或方法?

1 个答案:

答案 0 :(得分:4)

您应该能够使用openssl x509命令从X509证书中提取公钥组件。您说您的证书文件具有.cer扩展名,这通常表示二进制DER格式,因此该命令应该以pycrypto可以使用的形式提取公钥:

openssl x509 -inform der -pubkey -noout -in certificate.cer >public_key.pem

虽然,您的.cer文件可能已经是PEM格式(我怀疑这是因为在C#中你需要base64解码这个证书),在这种情况下这个命令应该得到公钥:

openssl x509 -pubkey -noout -in certificate.cer >public_key.pem

无论哪种方式,您都应该使用类似于此PEM格式密钥的文件public_key.pem

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8ZtNvMVc3iDc850hdWu
7LLw4CQfE4O4IKy7mv6Iu6uhHQsfRQCqSbc1Nwxq70dMudG+41cSBI2Sx7bsAby2
2seBOCCtcoXmDvyBbAetaHY4xUTXzMZKxZc+ZPRR5vB+suxW9yWCTUmYyxaY3SPx
iZHRF5dAmSbW4qIrXt+9ifIbGlMtzFBBetA9KgxVcBQB6VhJEHoLk4KL4R7tOoAQ
gs6WijTwzNfTubRQh1VUCbidQihVAOWMNVS/3SWRRrcN5V2DqOWL+4TkPK522sRD
K1t0C/i+XWjxeFu1zn3xXZlA2sruOIFQvpihbLgkrfOvjA/XESgshBhMfbXZjzC1
GwIDAQAB
-----END PUBLIC KEY-----

现在您可以使用Crypto.PublicKey.RSA.importKey()加载此内容。

您还应该仔细检查数据和签名的编码;确保这些是你假设的base64编码,虽然这可能是正确的,因为你有它在C#中工作。

存在其他选择:

  1. 使用好旧的pyOpenSSL - 请参阅模块OpenSSL.crypto

    import OpenSSL
    
    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1,
                                           open('certificate.cer').read())
    try:
        OpenSSL.crypto.verify(cert, signature, data, 'sha256')
        print "Signature verified OK"
    except Exception as e:
        print "Signature verification failed: {}".format(e)
    
  2. 使用M2Crypto(支持Python 3 ):

    import M2Crypto
    
    cert = M2Crypto.X509.load_cert('certificate.cer', M2Crypto.X509.FORMAT_DER)
    pubkey = cert.get_pubkey()
    pubkey.reset_context('sha256')
    pubkey.verify_init()
    pubkey.verify_update(content)
    verified = pubkey.verify_final(signature)