问题
I have a .cer file containing public key. I need to use this file to verify signature signed by corresponding private key. I have the signature and public key. I need to verify the signature. I'm getting result as false. Below is the code:
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
I tried to use method here to convert .cer file to .pem. How do I use a X509 certificate with PyCrypto?
Is the method used here is correct? or does python has better libraries. Because as far as i know, python does not support X.509Certificate. Bear my english. Appreciate any help.
Thanks.
Edit:
As of now, i'm trying to use Pycrypto. Do i need to use any other libraries or method in the same pycrypto?
回答1:
You should be able to extract the public key component from the X509 certificate using the openssl x509
command. You say that your certificate file has a .cer
extension which often means a binary DER format, so this command should extract the public key in a form that can be used by pycrypto:
openssl x509 -inform der -pubkey -noout -in certificate.cer >public_key.pem
Although, it's possible that your .cer
file is already in PEM format (I suspect that it is because in C# you needed to base64 decode this certificate), in which case this command should get the public key:
openssl x509 -pubkey -noout -in certificate.cer >public_key.pem
Either way you should end up with a file public_key.pem
that resembles this PEM format key:
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8ZtNvMVc3iDc850hdWu 7LLw4CQfE4O4IKy7mv6Iu6uhHQsfRQCqSbc1Nwxq70dMudG+41cSBI2Sx7bsAby2 2seBOCCtcoXmDvyBbAetaHY4xUTXzMZKxZc+ZPRR5vB+suxW9yWCTUmYyxaY3SPx iZHRF5dAmSbW4qIrXt+9ifIbGlMtzFBBetA9KgxVcBQB6VhJEHoLk4KL4R7tOoAQ gs6WijTwzNfTubRQh1VUCbidQihVAOWMNVS/3SWRRrcN5V2DqOWL+4TkPK522sRD K1t0C/i+XWjxeFu1zn3xXZlA2sruOIFQvpihbLgkrfOvjA/XESgshBhMfbXZjzC1 GwIDAQAB -----END PUBLIC KEY-----
Now you can load this using Crypto.PublicKey.RSA.importKey()
.
You also should double check the encoding of data and signature; make sure that these are base64 encoded as you assume, although this is probably correct since you have it working in C#.
Other options exist:
Use good old pyOpenSSL - see module 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)
Use M2Crypto (Python 3 not supported):
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)
来源:https://stackoverflow.com/questions/27229385/python-open-with-cer-file-to-get-public-key-and-then-perform-verification