关于python smime签名验证的问题

2 人关注

我们的服务是运行python的,突然间我无法从其他人那里验证java签名的签名。

我试着在java中验证,成功了......。

在没有对代码和证书文件做任何修改的情况下,它就突然发生了。

和合作伙伴也声称他们没有任何改变

这里是java代码,它返回true

public static boolean verifySignature(String rawMsg, final String signedMsg, X509Certificate certificate) {
        try {
            if (Security.getProvider("BC") == null) {
                Security.addProvider(new BouncyCastleProvider());
            CMSProcessableByteArray digestContent = new CMSProcessableByteArray(rawMsg.getBytes());
            CMSSignedData Signed = new CMSSignedData(digestContent, Base64.getDecoder().decode(signedMsg.getBytes()));
            SignerInformation Signer = (SignerInformation) Signed.getSignerInfos().getSigners().iterator().next();
            return Signer.verify(certificate, "BC");
        } catch (Exception e) {
            e.printStackTrace();
        return false;
    public static void main(String[] args) throws Exception {
        if (Security.getProvider("BC") == null)
            Security.addProvider(new BouncyCastleProvider());
        String publicKey = "-----BEGIN CERTIFICATE-----\r\n" + 
                "MIICWDCCAcGgAwIBAgIJANlZ7YIVy5L8MA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV\r\n" + 
                "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\r\n" + 
                "aWRnaXRzIFB0eSBMdGQwHhcNMTgxMjA4MDIyNzQzWhcNMTkxMjA4MDIyNzQzWjBF\r\n" + 
                "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\r\n" + 
                "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\r\n" + 
                "gQDwhejRDjKm80CTtaQvCHnaifscZVM37UkJxy7b++wi842yiyN4kVBvfZ9OHH8H\r\n" + 
                "isO7tfIG2ofn2TKdqWbepCYvq6TQ0/AQAahpJTTktFGUE7eWiABqxCZctnv3STe3\r\n" + 
                "Yj8PywEsjLTxbqGXhj5xZwQjGE5DNpRdwmbemANiZmrKYwIDAQABo1AwTjAdBgNV\r\n" + 
                "HQ4EFgQUK3guJRzCAJGpOOnwG+AeWAxVJmUwHwYDVR0jBBgwFoAUK3guJRzCAJGp\r\n" + 
                "OOnwG+AeWAxVJmUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQAgBsyA\r\n" + 
                "Pl6NHdiJphVZsJoYV1185kS4+e4sVXjwohWRWfEboxdv7s4uZ9Bw792cgrWG3TPn\r\n" + 
                "Z2Lzg5Y+CjtPGrd7Yc2vC+xUVv+Roj+X3QYCCn5z8peJXTK2xlsydWlV0pzlJDuX\r\n" + 
                "pirVw+4A51cbyc3orGrmldU0U9GN9N2wn1p10g==\r\n" + 
                "-----END CERTIFICATE-----\r\n" + 
        String msg = "{\"transactionInfo\":{\"cRefNum\":\"ocbtest191210000001\",\"clientCode\":\"Airpay\",\"pRefNum\":\"5def621cb91b43440905caf8f9dd59ed\",\"transactionReturn\":\"100\",\"transactionReturnMsg\":\"Account is not yet linked system or invalid data\"}}";
        System.out.println(msg);
        String signature = "MIIBKgYJKoZIhvcNAQcCoIIBGzCCARcCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGB9zCB9AIBATBSMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQCCQDZWe2CFcuS/DAJBgUrDgMCGgUAMA0GCSqGSIb3DQEBAQUABIGAGZnn9GZS80RHtseXsewKCR8gKJ9UvfrNUH1LzYnr5rUClpSSE9dN+ZB2oORUstAtKcvS4j9UHQYel5ooGvzYa+1LlnX12LwfVYAOXecMz2ZT0GUaAfmPyPRYg+rsc63SgPzVIDHAT7Va5EJ6JUx+qncP14f4AeUmEyJfbIff5ro=";
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509", "BC");
        X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(publicKey.getBytes()));
        System.out.println("Verify: " + CryptographyUtils.verifySignature(msg, signature, certificate));

这里是Python代码,几乎来自于文档中的示例代码

def pkcs7_verify(cert_path, raw_data, signature):
    sig = '\n'.join(chunk_string(signature, 64))
    out = '''MIME-Version: 1.0
Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----"
This is an S/MIME signed message
------
------
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"
--------''' % (raw_data, sig)
    # print out
    # Instantiate an SMIME object.
    s = SMIME.SMIME()
    # Load the signer's cert.
    x509 = X509.load_cert(cert_path)
    sk = X509.X509_Stack()
    sk.push(x509)
    s.set_x509_stack(sk)
    # Load the signer's CA cert. In this case, because the signer's
    # cert is self-signed, it is the signer's cert itself.
    st = X509.X509_Store()
    st.load_info(cert_path)
    s.set_x509_store(st)
    # Load the data, verify it.
        p7_bio = BIO.MemoryBuffer(out)
        p7, data_bio = SMIME.smime_load_pkcs7_bio(p7_bio)
        v = s.verify(p7, p7_bio)
    except Exception:
        import traceback
        traceback.print_exc()
        return False
    return True

它只是提高了

Traceback (most recent call last):
  File "/Users/xxx/Develop/python/scripts/sign.py", line 46, in pkcs7_verify
    v = s.verify(p7, p7_bio)
  File "/Users/xxx/.virtualenvs/giro/lib/python2.7/site-packages/M2Crypto/SMIME.py", line 262, in verify
    data_bio._ptr(), flags)
PKCS7_Error: certificate verify error

new cert

-----BEGIN CERTIFICATE-----
MIIChDCCAe2gAwIBAgIJAK/KaxzV02sPMA0GCSqGSIb3DQEBCwUAMFsxCzAJBgNV
BAYTAlZOMQwwCgYDVQQIDANIQ00xFDASBgNVBAcMC0hvIENoaSBNaW5oMQwwCgYD
VQQKDANPQ0IxDDAKBgNVBAsMA09DQjEMMAoGA1UEAwwDT0NCMB4XDTE5MTIxMzA2
NTY1OVoXDTI0MTIxMTA2NTY1OVowWzELMAkGA1UEBhMCVk4xDDAKBgNVBAgMA0hD
TTEUMBIGA1UEBwwLSG8gQ2hpIE1pbmgxDDAKBgNVBAoMA09DQjEMMAoGA1UECwwD
T0NCMQwwCgYDVQQDDANPQ0IwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPCF
6NEOMqbzQJO1pC8IedqJ+xxlUzftSQnHLtv77CLzjbKLI3iRUG99n04cfweKw7u1
8gbah+fZMp2pZt6kJi+rpNDT8BABqGklNOS0UZQTt5aIAGrEJly2e/dJN7diPw/L
ASyMtPFuoZeGPnFnBCMYTkM2lF3CZt6YA2JmaspjAgMBAAGjUDBOMB0GA1UdDgQW
BBQreC4lHMIAkak46fAb4B5YDFUmZTAfBgNVHSMEGDAWgBQreC4lHMIAkak46fAb
4B5YDFUmZTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBANzvwH3Hs5Av
iuK4MK3lUScfmShusdHCDHYh+boF7TIQNW9f1fJijNnHOk92antONyZYCcfhiiT0
6bpok9XtpAnYurNI4nimQPhb2/kBKyW2xhmLEbRD2QAzXiw85qF6yTOqjsOKgqHP
fenzMFLsJRRVcNe89cs2kC1qMP2zure+
-----END CERTIFICATE-----
    
python
cryptography
Zhihong Lin
Zhihong Lin
发布于 2019-12-12
1 个回答
Topaco
Topaco
发布于 2019-12-12
已采纳
0 人赞同

证书 expired 几天前( Dec 8 02:27:43 2019 GMT )。以下是OpenSSl-statement。 [1] :

openssl x509 -enddate -noout -in <path to certificate>

results in:

notAfter=Dec 8 02:27:43 2019 GMT

这可能是造成这个问题的原因。 这也符合没有修改代码的情况。这两段代码似乎对过期证书的处理方式不同。如果在Java-code中。[2]:

certificate.checkValidity();