PKCS7 Verify digital signature in Java

Manfred picture Manfred · Jun 11, 2013 · Viewed 12.3k times · Source

The situation is that i have to check a digital signature:

String1 "A1005056807CE11EE2B4CE0025305725CFrCN=KED,OU=I0020266601,OU=SAPWebAS,O=SAPTrustCommunity,C=DE20130611102236" is signed via PKCS#7 and send over HTTP-URL to me.

I get the signed content in BASE64 (look in code String sc).

Now i have to check, if the Hash of String1 which i will reproduce later in my code, is the same as from the signed content. Therefore i have to use the public key which i have from a certificate.

I have a file with a X.509 certificate. This file i load into a X509Certificate instance. I got this file by copy and paste the bytes out from SAP- so i am not sure if the certificate is correct. But i can load it into the instance - i have putted the output of this certificate below.

Now i get "message-digest attribute value does not match calculated value" when i run my code. I dont know if these steps are right and is this message is correct, or am I doing something false!?

Here my code:

String sc = "MIIBUQYJKoZIhvcNAQcCoIIBQjCCAT4CAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGCAR0wggEZAgEBMG8wZDELMAkGA1UEBhMCREUxHDAaBgNVBAoTE1NBUCBUcnVzdCBDb21tdW5pdHkxEzARBgNVBAsTClNBUCBXZWIgQVMxFDASBgNVBAsTC0kwMDIwMjY2NjAxMQwwCgYDVQQDEwNLRUQCByASEgITMlYwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTEzMDYxMTA4MjM1MVowIwYJKoZIhvcNAQkEMRYEFGy7jXb/pUqMYdk2dss2Qe6hNroaMAkGByqGSM44BAMELjAsAhRMJ+t5/3RxQAsHKnIoPY4BnO0qCAIUAbKRwWNjOYsewB56zoZqnZwRyWw=";
byte[] secKey = Base64.decode(sc);


CMSSignedData s = new CMSSignedData(secKey);

SignerInformationStore signers = s.getSignerInfos();
Iterator<SignerInformation> it = signers.getSigners().iterator();

FileInputStream fis = new FileInputStream("c:\\sap.cer");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Collection<X509Certificate> c = (Collection<X509Certificate>)cf.generateCertificates(fis);
Iterator<X509Certificate> i = c.iterator();

while(it.hasNext()){
    SignerInformation signer = it.next();
    while (i.hasNext()) {
        X509Certificate cert = i.next();
        cert.checkValidity();
        cert.verify(cert.getPublicKey());           
        signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("SUN").build(cert));
    }
}

Certificate Output:

[
[
  Version: V1
  Subject: CN=KED, OU=I0020266601, OU=SAP Web AS, O=SAP Trust Community, C=DE
  Signature Algorithm: SHA1withDSA, OID = 1.2.840.10040.4.3

  Key:  Sun DSA Public Key
    Parameters:DSA
    p:     ffd22469 8c53aa90 7585c3ee b65ffd9a cde5b230 53041af9 969e69c8 22093f5a
    477740c5 d398084f 3830ea33 8dbd8505 d6cce42b 135794b1 a971e670 f896eee2
    17acf3f8 48c67d35 434768d7 9c30567f abeb0d86 5674ef2b d391d530 26cbd9ba
    647414ba ff6e2f5b 9f468df7 3e266bd5 b330058d e64cfd69 75065322 11c43237
    q:     cd1ac6c7 d55ae243 cd5bbb0c 0f0789b4 233786b1
    g:     0945535b 061de39c 995832d2 03d3c2a0 c352cad9 2a524886 7c681962 ca94e5e3
    f23cc4c0 7891bc0d 0abc85fe 4f575334 b8e02d02 176d7534 ec7080c3 a46ccba3
    776a1b2f fa6f3586 e4e90e40 558e779a 6d90c9c0 c788592f 5d8ffe16 801e2c9e
    b3305ed3 c4035015 a246b7fc 2d2dda7f e6431fe3 d3b291fe 58082643 49d9bac1

  y:
    cab5984a d0254277 fd4aab43 799d8120 35f7725b 313b87a2 ca092c91 96236e44
    8ad7c157 d000395b 1ce37da2 a9c18113 c34067e8 c917752b 9604049d 70b92bb0
    6aa65d45 d5fde439 bbcbaa21 7520542a baac4e64 75fabc57 56a91856 178d8fc4
    6aa34d71 5a06b59f 6c89ae81 3571d4ce 89bbeb49 dedfc68c 4fa8a6d1 9aefcdcf

  Validity: [From: Sun Dec 02 14:32:56 CET 2012,
               To: Fri Jan 01 01:00:01 CET 2038]
  Issuer: CN=KED, OU=I0020266601, OU=SAP Web AS, O=SAP Trust Community, C=DE
  SerialNumber: [    20121202 133256]

]
  Algorithm: [SHA1withDSA]
  Signature:
0000: 30 2D 02 14 15 BE 80 34   1A 6F 02 F4 C8 5A 9A 6A  0-.....4.o...Z.j
0010: 3E 5A A8 66 C2 A2 AD 3C   02 15 00 C9 53 A6 D9 85  >Z.f...<....S...
0020: 3F 22 FB 12 5C E9 9D B7   77 29 03 62 81 EA 17     ?"..\...w).b...

]

Answer

Manfred picture Manfred · Jun 12, 2013

Finally i got it with help of this: verifying detached signature with BC

    String toVerify = "A1005056807CE11EE2B4CE0025305725CFrCN%3DKED,OU%3DI0020266601,OU%3DSAPWebAS,O%3DSAPTrustCommunity,C%3DDE20130611102236";
    String signed = "MIIBUQYJKoZIhvcNAQcCoIIBQjCCAT4CAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGCAR0wggEZAgEBMG8wZDELMAkGA1UEBhMCREUxHDAaBgNVBAoTE1NBUCBUcnVzdCBDb21tdW5pdHkxEzARBgNVBAsTClNBUCBXZWIgQVMxFDASBgNVBAsTC0kwMDIwMjY2NjAxMQwwCgYDVQQDEwNLRUQCByASEgITMlYwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTEzMDYxMTA4MjM1MVowIwYJKoZIhvcNAQkEMRYEFGy7jXb/pUqMYdk2dss2Qe6hNroaMAkGByqGSM44BAMELjAsAhRMJ+t5/3RxQAsHKnIoPY4BnO0qCAIUAbKRwWNjOYsewB56zoZqnZwRyWw=";
    byte[] signedByte = Base64.decode(signed);

    Security.addProvider(new BouncyCastleProvider());

    CMSSignedData s = new CMSSignedData(new CMSProcessableByteArray(toVerify.getBytes()), signedByte);
    SignerInformationStore signers = s.getSignerInfos();
    SignerInformation signerInfo = (SignerInformation)signers.getSigners().iterator().next();

    FileInputStream fis = new FileInputStream("c:\\sap.cer");
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    X509Certificate cert = (X509Certificate)cf.generateCertificates(fis).iterator().next();

    boolean result = signerInfo.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("SUN").build(cert.getPublicKey())); 
    System.out.println("Verified: "+result);