Search code examples
javapythonrsadigital-signaturepycrypto

SHA1withRSA verify in python?


I want to rewrite the code of Java to Python.The code is used to verify data through a .cer file.

public static boolean verifyByRSA(String certPath, byte[] aPlainData,
        byte[] aSignature) {
    boolean tResult = false;
    try {
        InputStream inStream = new FileInputStream(certPath);
        CertificateFactory tCertFactory = CertificateFactory
                .getInstance("X.509");
        Certificate tCertificate = tCertFactory
                .generateCertificate(inStream);

        Signature tSign = Signature.getInstance("SHA1withRSA", "BC");
        tSign.initVerify(tCertificate);

        tSign.update(aPlainData);
        tResult = tSign.verify(aSignature);

    } catch (Exception e) {
        e.printStackTrace();
    }
    return tResult;
}

The .cer file is like:

-----BEGIN CERTIFICATE----- MIIDhzCCAm+gAwIBAgIGASYISh96MA0GCSqGSIb3DQEBBQUAMF8xCzAJBgNVBAYTAkNOMSkwJwYDVQQKDCBBbGxpbnBheSBOZXR3b3JrIFNlcnZpY2VzIENvLkx0ZDElMCMGA1UECwwcQWxsaW5wYXkgUHJpbWFyeSBDZXJ0aWZpY2F0ZTAeFw0xMDAxMDcxMDE3NDBaFw0zMDAxMDIxMDE3NDBaMGQxCzAJBgNVBAYTAkNOMSkwJwYDVQQKDCBBbGxpbnBheSBOZXR3b3JrIFNlcnZpY2VzIENvLkx0ZDEqMCgGA1UECwwhQWxsaW5wYXkgRGlnaXRhbCBTaWduIENlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEv2q2/xN5PF0dLn1vhIaVlyWsvJFVFxWgH7sQBObzYbZXOOVzoQpmXuSFOrF0/ol4Okd/2OGfdXUUFSUZfzAQOT1Wmjupec7z2V6l4/PT7aOg6t/MJwU9aW9Iw+AFzM1vnLOXdTlWVLZbtB7IiJ/HhfwBDkyvhp1zNYoAPrwC5QIDAQABo4HHMIHEMB0GA1UdDgQWBBQlWQA//YbuEdfE1yP+PpnokDO8WDCBjgYDVR0jBIGGMIGDgBSBWR3Bvx8To7TrecKhCM4smeabN6FjpGEwXzELMAkGA1UEBhMCQ04xKTAnBgNVBAoMIEFsbGlucGF5IE5ldHdvcmsgU2VydmljZXMgQ28uTHRkMSUwIwYDVQQLDBxBbGxpbnBheSBQcmltYXJ5IENlcnRpZmljYXRlggYBJghKHowwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQUFAAOCAQEATzT9GuAmAXLSWpoGc0F7Km7DPMWvSAkq8ckJLftF0/lB3JTR6QT5rsTnQHCdRU7SJX+eLNwhJQdRg34dPJAI2z/HpgGu7tW7pdsHjCjlVae3I64h2OzYBGXdtdRyPmyXfBOgXUfqtH0Fg+1QqsRmcRugywjZH8ZQAVYm0TkVJmdBknPp60bJ2gE/nj0w6VaSL6HMAQ+A7AVne3NDreBXepMHgiFqiqMHrZFBQCgTSR1UwZoT8hwXaaUgwf2h9l/D2QOGCD8G3sRKfMsH3clkehXbprWPNk3uww7dCT0pGz845AyKzCmRK60Z/NOgMG5X+f+JmugsS/bKYwjetXHg9Q== -----END CERTIFICATE-----

I have tried

from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA

key = RSA.importKey(open(cer_path).read())
signer = PKCS1_v1_5.new(key)
digest = SHA.new()
digest.update(str_to_sign)
if signer.verify(digest, base64.decodestring(signature)):
    return True
return False  

But can't get the right result.What does the java code means?


Solution

  • The importKey function supports the following:

    • X.509 subjectPublicKeyInfo DER SEQUENCE (binary or PEM encoding)
    • PKCS#1 RSAPublicKey DER SEQUENCE (binary or PEM encoding)
    • OpenSSH (textual public key only)

    Now only the first and second are part of an X.509 certificate.

    You need a library to parse X.509 certificates, such as the cryptography package.

    As a stopgap measure you can get the RSAPublicKey object in your Java code and call getEncoded. This will return a DER SEQUENCE with a subjectPublicKeyInfo that can be imported in Python crypto (the first supported format by the importKey function).