Quantcast

Using RSASSA-PSS signature algorithm to verify a certificate in Java

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Using RSASSA-PSS signature algorithm to verify a certificate in Java

golchhamohit
I'm very new to certificate concept and I would like to know how to verify signature of a certificate with RSASSA-PSS algorithm (OID - 1.2.840.113549.1.1.10).


package com.learn.package.certificates;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

public class VerifyCertificate {

    public static void main(String[] args) throws InvalidKeyException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException, SignatureException {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        X509Certificate clientCert = ...;
        X509Certificate caCert = ...;
        clientCert.verify(caCert.getPublicKey(), "BC");
    }
}


Exception trace:

Exception in thread "main" java.security.SignatureException: Signature does not match.
    at sun.security.x509.X509CertImpl.verify(X509CertImpl.java:449)
    at com.learn.package.certificates.VerifyCertificate.main(VerifyCertificate.java:33)

Can somebody help what could be the issue here?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using RSASSA-PSS signature algorithm to verify a certificate in Java

golchhamohit
Hi,


Seems like verifying signatures manually is the only way to do? I was able to verify the certificate by constructing the signature and setting PSSParameterSpec and MGF1ParameterSpec.

package com.learn.package.certificates;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.security.Security;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PSSParameterSpec;
import java.util.Base64;

public class ManualCertVerification {

    public static void main(String[] args) throws Exception {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        X509Certificate clientCert = ...;

        X509Certificate caCert = ...;

        Signature signature = Signature.getInstance(clientCert.getSigAlgName(), "BC");
        signature.setParameter(new PSSParameterSpec("SHA-256", "MGF1",
                new MGF1ParameterSpec("SHA-256"), 32, 1));
        signature.initVerify(caCert.getPublicKey());
        signature.update(clientCert.getTBSCertificate());
        boolean r = signature.verify(clientCert.getSignature()); // returns true
    }
}
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using RSASSA-PSS signature algorithm to verify a certificate in Java

Eckenfels. Bernd
Hello,

I would think this is more a JCE question if you use the CertPath checking of the X509Certificate.

Did you test your manual checks against those samples? http://www.kaiser.cx/x509Pss.html
Can you provide a sample for a cert to test?
Can you name which CA or industrie would use those?

Note that in RFC 4050 there are some additional parameter verifications defined. If you do the manual checks, you also need to implement them.

(And I admit I currently don't know if or if not BC or JCE has validation methods for any of those variants. Proper certpath checking could get rather ugly if not)

Gruss
Bernd
--
http://www.seeburger.com
________________________________________
From: golchhamohit [[hidden email]]
Sent: Wednesday, April 05, 2017 06:52
To: [hidden email]
Subject: [dev-crypto] Re: Using RSASSA-PSS signature algorithm to verify a certificate in Java

Hi,


Seems like verifying signatures manually is the only way to do? I was able
to verify the certificate by constructing the signature and setting
PSSParameterSpec and MGF1ParameterSpec.

package com.learn.package.certificates;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.security.Security;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PSSParameterSpec;
import java.util.Base64;

public class ManualCertVerification {

    public static void main(String[] args) throws Exception {
        Security.addProvider(new
org.bouncycastle.jce.provider.BouncyCastleProvider());

        X509Certificate clientCert = ...;

        X509Certificate caCert = ...;

        Signature signature =
Signature.getInstance(clientCert.getSigAlgName(), "BC");
        signature.setParameter(new PSSParameterSpec("SHA-256", "MGF1",
                new MGF1ParameterSpec("SHA-256"), 32, 1));
        signature.initVerify(caCert.getPublicKey());
        signature.update(clientCert.getTBSCertificate());
        boolean r = signature.verify(clientCert.getSignature()); // returns
true
    }
}




--
View this message in context: http://bouncy-castle.1462172.n4.nabble.com/Using-RSASSA-PSS-signature-algorithm-to-verify-a-certificate-in-Java-tp4658632p4658633.html
Sent from the Bouncy Castle - Dev mailing list archive at Nabble.com.








SEEBURGER AG            Vorstand/SEEBURGER Executive Board:
Sitz der Gesellschaft/Registered Office:                Axel Haas, Michael Kleeberg, Friedemann Heinz, Dr. Martin Kuntz, Matthias Feßenbecker
Edisonstr. 1
D-75015 Bretten         Vorsitzende des Aufsichtsrats/Chairperson of the SEEBURGER Supervisory Board:
Tel.: 07252 / 96 - 0            Prof. Dr. Simone Zeuchner
Fax: 07252 / 96 - 2222
Internet: http://www.seeburger.de               Registergericht/Commercial Register:
e-mail: [hidden email]               HRB 240708 Mannheim


Dieses E-Mail ist nur für den Empfänger bestimmt, an den es gerichtet ist und kann vertrauliches bzw. unter das Berufsgeheimnis fallendes Material enthalten. Jegliche darin enthaltene Ansicht oder Meinungsäußerung ist die des Autors und stellt nicht notwendigerweise die Ansicht oder Meinung der SEEBURGER AG dar. Sind Sie nicht der Empfänger, so haben Sie diese E-Mail irrtümlich erhalten und jegliche Verwendung, Veröffentlichung, Weiterleitung, Abschrift oder jeglicher Druck dieser E-Mail ist strengstens untersagt. Weder die SEEBURGER AG noch der Absender (Eckenfels. Bernd) übernehmen die Haftung für Viren; es obliegt Ihrer Verantwortung, die E-Mail und deren Anhänge auf Viren zu prüfen.


This email is intended only for the recipient(s) to whom it is addressed. This email may contain confidential material that may be protected by professional secrecy. Any fact or opinion contained, or expression of the material herein, does not necessarily reflect that of SEEBURGER AG. If you are not the addressee or if you have received this email in error, any use, publication or distribution including forwarding, copying or printing is strictly prohibited. Neither SEEBURGER AG, nor the sender (Eckenfels. Bernd) accept liability for viruses; it is your responsibility to check this email and its attachments for viruses.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using RSASSA-PSS signature algorithm to verify a certificate in Java

golchhamohit
Hi Bernd,

Thanks for the samples. I tested against them and they worked fine. The only difference I could see between the samples and mine are they are hashed with sha-256 whereas example has been hashed with sha-1. Is it possible that BC doesn't have provider support for SHA-256 with PSS? This thread seemed to have similar problem but was 2 years back. Any idea how can I confirm that does BC have support for SHA-256 along with PSS?

Meanwhile, I shall try to provide example certs for testing.

Thanks.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using RSASSA-PSS signature algorithm to verify a certificate in Java

David Hook-3

I'd be suspicious of the parameters (or lack of them) in the
AlgorithmIdentifier structures in the certs you have been given.

There's examples of SHA-1, as well as SHA-224, SHA-256, and SHA-384 in
the org.bouncycastle.cert.test .CertTest class

The creation functions are called at lines 3094-3097.

Regards,

David

On 06/04/17 14:45, golchhamohit wrote:

> Hi Bernd,
>
> Thanks for the samples. I tested against them and they worked fine. The only
> difference I could see between the samples and mine are they are hashed with
> sha-256 whereas example has been hashed with sha-1. Is it possible that BC
> doesn't have provider support for SHA-256 with PSS? This  thread
> <http://bouncy-castle.1462172.n4.nabble.com/RSA-PSS-verification-from-digest-value-td4414137.html#a4414275>  
> seemed to have similar problem but was 2 years back. Any idea how can I
> confirm that does BC have support for SHA-256 along with PSS?
>
> Meanwhile, I shall try to provide example certs for testing.
>
> Thanks.
>
>
>
> --
> View this message in context: http://bouncy-castle.1462172.n4.nabble.com/Using-RSASSA-PSS-signature-algorithm-to-verify-a-certificate-in-Java-tp4658632p4658640.html
> Sent from the Bouncy Castle - Dev mailing list archive at Nabble.com.
>
>



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Using RSASSA-PSS signature algorithm to verify a certificate in Java

golchhamohit
f1-dak.pem
f1-device.pem

logs.txt

Hi David,

I'm sorry for stretching this thread and replying lately. Please find the entire code(cert path validation) below with certificates in base64 DER format. While starting this thread, I started with normal certificate verification but then tried to do validation based on cert path (which follows RFC-5280 standards - https://tools.ietf.org/html/rfc5280#section-6) I have attached logs.txt file, this has the entire debug logs(after enabling -Djava.security.debug="all").

Please let me know what is the issue here..I have been struck here for days now.. Thanks in advance.

import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.Security;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertStore;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.PKIXCertPathBuilderResult;
import java.security.cert.TrustAnchor;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.HashSet;
import java.util.Set;

public class f1_CertificateVerifyChain {

    private static X509Certificate clientCertificate;
    private static X509Certificate caCertificate;

    public static void main(String[] args) throws Exception {

        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        // self generated cert
        final String base64Certificate = "MIIDnTCCAlWgAwIBAgIJAKbFBvoaUS35MD0GCSqGSIb3DQEBCjAwoA0wCwYJYIZIAWUDBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIDAgEgMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTcwNDIwMTEyNTAwWhcNMjcwNDE4MTEyNTAwWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4duCvIvpJYYYDWCCIfLeRmX3/qpm68g4gzDC3jI+rrjTXhZZKOw4YtB4UzivdtBd62EW+8KGi2IQ3XkdnZwZqeGtCVlJ/2hEnA9ahhMMjHkFgQKqEfjtC5nORS3Do9HfrmcX9OWJ9QWtT6xVpyFoOcePVW3fwAhstZmooB1NdqcLbOlBS8SSJ5vaewNUb/invMT6Uy0AaisgTduCBbY4592wQrZUbpujEqWK+WJa6eyIhpMqFjKX685zKwcxxqsEbtSAFgyzi3J+5e4JmV7FdilhZlCgDM7eJrvsdauI08LvTotkNoyCe4i+PLQ/z6AGs4h3cf6jF3k5XaRtxPeEXwIDAQABozAwLjAfBgNVHSMEGDAWgBS0Ui0x/2xd9sXVtuyy5Pez8f8CnjALBgNVHQ8EBAMCBaAwPQYJKoZIhvcNAQEKMDCgDTALBglghkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogMCASADggEBACXmJezJXKedkpGwVesRmwuCl6Ys+eBfRftTqzwbUYmdfZ3BNjDFMamdcYN+Io1uQZnmLgpZWYg53SfHuc8qiLeZdR9Y5BSt/MqDrvPp29fMe01OmAXPghWYNyaop4v+7GkqIt70tEAafsTQnPOqXaiC3rFUCzx4bRN1Fbln1DopmbBX0LrYl8Wsva0JyqrhHSfw6b6j4WDPb7FCkMCOhU6wI0GZ7d0g1GHFHFthx+wMF0iPBWZsMhX/gqidOtNjeRKNjTpLf7p1ZVSCwVz0xNGcbemiMOQMw1gJ17bAL0rkdKcszAxxcaANBiaHhMm4GHd+AJKUgVhC3XWR7dsGGKk=";

        ByteBuffer buffer1 = ByteBuffer.wrap(base64Certificate.getBytes());
        clientCertificate = CertificateVerifyNormal.extractX509Certificate(Base64.getDecoder().decode(buffer1.array()));

        // self generated cert
        final String base64Dak = "MIIDvzCCAnegAwIBAgIJAMZrDhy9RpnKMD0GCSqGSIb3DQEBCjAwoA0wCwYJYIZIAWUDBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIDAgEgMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwIBcNMTcwNDIwMTEyNDM3WhgPMjExNzAzMjcxMTI0MzdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMX5RoUHewkq/UnXcUORGMbnBg3jXGdu/r1r+H4eMPmjRleP2D0sjeSbut5Ef0qWDoTgxgIQ56PLLhtsPXE/6AYbg16pfpdnVFZzmgj9Rb6af4REQ3G8QqecoD4ScHPyebE85kXe99msQZH3eEY+vnWzXwXFuYKKCR+f4naVuMH+q+/66NvQYIg6aOLjLEpCMvYWaEKmCdW6tYL3VAgV4oPIf9nRF7UHy8vr1UqDJCqETuLGKZb3psLGNOOYkD4UbltBADYHWI5iGF2GjBOmf0kMtUbAuJhDkDWZ7a5YDxXhhC2ORC2Pvw5kPGAg3RWVp7SMRFx6AYF6pLUZZB19j1AgMBAAGjUDBOMB0GA1UdDgQWBBS0Ui0x/2xd9sXVtuyy5Pez8f8CnjAfBgNVHSMEGDAWgBS0Ui0x/2xd9sXVtuyy5Pez8f8CnjAMBgNVHRMEBTADAQH/MD0GCSqGSIb3DQEBCjAwoA0wCwYJYIZIAWUDBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIDAgEgA4IBAQCCw80z8uJwA8I+M0zVFYzTcfZxouY87FqOlEmt0lb2QdPbubGn8ucQkB7Ki0THyszNnAzgGVCDJcq6Q3f7dDFz6ZBi1GzJ+kVIuROxI8f2FZeW7B39/4m4zgJEYvbfQrjWm+cCiS2dC5SkYsNemW0wb0GXoRQYvSiRX3V0fKq3LYxBcELA7tdcJi5UIL03dPCMyN2hp6vq23/zCNdI29Kej2ze9Rrtqk7YdNgejdVY23DIHNTKkiPOHo9jJC72Znj7Cn3D4GThJZtVML3P/egqgy2gZrAgIozn2Swfzl7BBHRYAyFUWmLrf68CWwYWj8QsCf1u0o4LRXpV3af1wOTD";

        ByteBuffer buffer2 = ByteBuffer.wrap(base64Dak.getBytes());
        caCertificate = CertificateVerifyNormal.extractX509Certificate(Base64.getDecoder().decode(buffer2.array()));

        Set<X509Certificate> ics = new HashSet<>();
        ics.add(caCertificate);
        verifyCertificate(clientCertificate, ics, ics);
        System.out.println("completed");
    }

    private static PKIXCertPathBuilderResult verifyCertificate(X509Certificate cert, Set<X509Certificate> trustedRootCerts,
            Set<X509Certificate> intermediateCerts) throws GeneralSecurityException {
         
        // Create the selector that specifies the starting certificate
        X509CertSelector selector = new X509CertSelector();
        selector.setCertificate(cert);
         
        // Create the trust anchors (set of root CA certificates)
        Set<TrustAnchor> trustAnchors = new HashSet<>();
        for (X509Certificate trustedRootCert : trustedRootCerts) {
            trustAnchors.add(new TrustAnchor(trustedRootCert, null));
        }

        // Configure the PKIX certificate builder algorithm parameters
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());

        PKIXBuilderParameters pkixParams =
            new PKIXBuilderParameters(trustAnchors, selector);
       
         
        // Disable CRL checks (this is done manually as additional step)
        pkixParams.setRevocationEnabled(false);
     
        // Specify a list of intermediate certificates
        CertStore certStore = CertStore.getInstance("Collection",
            new CollectionCertStoreParameters(trustedRootCerts));
        pkixParams.addCertStore(certStore);

        // Build and verify the certification chain
        CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
        PKIXCertPathBuilderResult result =
            (PKIXCertPathBuilderResult) builder.build(pkixParams);
        return result;
    }
}
Loading...