Prime239v1 self-signed certificate cannot be verified

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Prime239v1 self-signed certificate cannot be verified

3ric_T

Hi

 

  When I try to verify a ECDSA prime239v1 self-signed certificate with BC version 1.64, it fails with the error: java.security.SignatureException: certificate does not verify with supplied key

 

  Here are a piece of code which can be used to reproduce:

@Test

  void verifyPublicKey() throws Exception {

  Security.addProvider( new BouncyCastleProvider() );

 

  String certificateAsString = "MIIBljCCAUGgAwIBAgISESEodJHbPEvphL8WrOaYt+HXMAoGCCqGSM49BAMCMB0xGzAZBgNVBAMMEkhTU1Rlc3RUb0JlUmVtb3ZlZDAgFw0xOTA5MDEwMDAwMDFaGA8yMDU0MDkwMTAwMDAwMVowHTEbMBkGA1UEAwwSSFNTVGVzdFRvQmVSZW1vdmVkMFUwEwYHKoZIzj0CAQYIKoZIzj0DAQQDPgAEAqBdSfsPUcy2smBkKEY1EsMal+b/3V4FoUQE+ye/NjVR2Cr35YEzkfHjfmFnjxLYEWZkNsLF/UpEgqXlo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBNjAdBgNVHQ4EFgQUMx33HrlnhuffFTo+nUgszc70GhswHwYDVR0jBBgwFoAUMx33HrlnhuffFTo+nUgszc70GhswCgYIKoZIzj0EAwIDQwAwQAIeVUy/xhOy6CAbgMRLTnbYSCsK5d5F2dx8yZJl/EmRAh43u+lUn5/K366BQwLUv9w6YlZSL7h9cfuidtRJi2Q=";

  CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME);

  final byte[] bytes = Base64.decode(certificateAsString);

  final ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);

  final X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(inputStream);

  final PublicKey publicKey = certificate.getPublicKey();

  certificate.verify(publicKey, BouncyCastleProvider.PROVIDER_NAME);

}

 

I debugged the code and it fails in this fragment of verifySignature method in ECDSASigner class, which retrun false:

 

This verification fails with SUN but succeeds with OpenSSL and the ASN1 structure of the certificate doesn't seem to be invalid.

 

Éric 

Reply | Threaded
Open this post in threaded view
|

Re: Prime239v1 self-signed certificate cannot be verified

David Hook-3

It looks alright to me as well. How are you verifying it in openSSL though? I've played around with the openssl verify command and it seems I can get it to print OK in a number of situations where I would not have expected it. Something clearly is not right here. Have you tried using java to sign a short message and then verify it? That would at least tell us if it's the signature or the certificate encoding that is the issue.

Regards,

David

On 12/12/19 12:58 am, Eric Tournier wrote:

Hi

 

  When I try to verify a ECDSA prime239v1 self-signed certificate with BC version 1.64, it fails with the error: java.security.SignatureException: certificate does not verify with supplied key

 

  Here are a piece of code which can be used to reproduce:

@Test

  void verifyPublicKey() throws Exception {

  Security.addProvider( new BouncyCastleProvider() );

 

  String certificateAsString = "MIIBljCCAUGgAwIBAgISESEodJHbPEvphL8WrOaYt+HXMAoGCCqGSM49BAMCMB0xGzAZBgNVBAMMEkhTU1Rlc3RUb0JlUmVtb3ZlZDAgFw0xOTA5MDEwMDAwMDFaGA8yMDU0MDkwMTAwMDAwMVowHTEbMBkGA1UEAwwSSFNTVGVzdFRvQmVSZW1vdmVkMFUwEwYHKoZIzj0CAQYIKoZIzj0DAQQDPgAEAqBdSfsPUcy2smBkKEY1EsMal+b/3V4FoUQE+ye/NjVR2Cr35YEzkfHjfmFnjxLYEWZkNsLF/UpEgqXlo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBNjAdBgNVHQ4EFgQUMx33HrlnhuffFTo+nUgszc70GhswHwYDVR0jBBgwFoAUMx33HrlnhuffFTo+nUgszc70GhswCgYIKoZIzj0EAwIDQwAwQAIeVUy/xhOy6CAbgMRLTnbYSCsK5d5F2dx8yZJl/EmRAh43u+lUn5/K366BQwLUv9w6YlZSL7h9cfuidtRJi2Q=";

  CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME);

  final byte[] bytes = Base64.decode(certificateAsString);

  final ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);

  final X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(inputStream);

  final PublicKey publicKey = certificate.getPublicKey();

  certificate.verify(publicKey, BouncyCastleProvider.PROVIDER_NAME);

}

 

I debugged the code and it fails in this fragment of verifySignature method in ECDSASigner class, which retrun false:

 

This verification fails with SUN but succeeds with OpenSSL and the ASN1 structure of the certificate doesn't seem to be invalid.

 

Éric 


Reply | Threaded
Open this post in threaded view
|

RE: Prime239v1 self-signed certificate cannot be verified

3ric_T

Hi everybody

 

  Thanks for the answer, David

  In fact OpenSSL is the only one which seems to verify the certificate without throwing an error, with the following:

#openssl verify -CAfile prime239v1.cer prime239v1.cer

  As I’m not an OpenSSL guru, I don’t know if it is lying or not. In fact both BC and SUN say that they cannot verify my self-signed certificate with its own public key

 

  I’ll try to sign something with the private key (which is in our HSM) and then verifying it. Then I go back here with the results

 

Éric

 

De : David Hook [mailto:[hidden email]]
Envoyé : jeudi 12 décembre 2019 01:56
À : [hidden email]
Objet : Re: [dev-crypto] Prime239v1 self-signed certificate cannot be verified

 

 

It looks alright to me as well. How are you verifying it in openSSL though? I've played around with the openssl verify command and it seems I can get it to print OK in a number of situations where I would not have expected it. Something clearly is not right here. Have you tried using java to sign a short message and then verify it? That would at least tell us if it's the signature or the certificate encoding that is the issue.

 

Regards,

 

David

 

 

Reply | Threaded
Open this post in threaded view
|

RE: Prime239v1 self-signed certificate cannot be verified

3ric_T

Hi,

 

  I tried to sign some text data after issuing a ECDSA prime239v1 certificate. The verification fails, here is the following code:

        Signature ecdsaVerify = Signature.getInstance("SHA256withECDSA", BouncyCastleProvider.PROVIDER_NAME);

        ecdsaVerify.initVerify(certificate.getPublicKey());

        ecdsaVerify.update(plaintext.getBytes("UTF-8"));

        boolean isValidSignature = ecdsaVerify.verify(Base64.decode(signatureAsString));

 

  The verification of my self-signed certificate with its own private key fails in this part of BC code (org.bouncycastle.crypto.signers.ECDSASigner):

        ECCurve curve = point.getCurve();

        if (curve != null)

        {

            BigInteger cofactor = curve.getCofactor();

            if (cofactor != null && cofactor.compareTo(EIGHT) <= 0)

            {

                ECFieldElement D = getDenominator(curve.getCoordinateSystem(), point);

                if (D != null && !D.isZero())

                {

                    ECFieldElement X = point.getXCoord();

                    while (curve.isValidFieldElement(r))

                    {

                        ECFieldElement R = curve.fromBigInteger(r).multiply(D);

                        if (R.equals(X))

                        {

                            return true;

                        }

                        r = r.add(n);

                    }

                    return false;

                }

            }

        }

 

  The debug shows that in the inner while, we cannot find any ECFieldEleement R which is equal to X. As I haven’t any idea of what it means (I have to work on mathematical basis of ECDSA) :D I need some help :)

  The offending certificate is (Base64 format):

-----BEGIN CERTIFICATE-----

MIIBljCCAUGgAwIBAgISESE/0HMzJQ81M17SAVeO0cQmMAoGCCqGSM49BAMCMB0x

GzAZBgNVBAMMEkhTU1Rlc3RUb0JlUmVtb3ZlZDAgFw0xOTA5MDEwMDAwMDFaGA8y

MDU0MDkwMTAwMDAwMVowHTEbMBkGA1UEAwwSSFNTVGVzdFRvQmVSZW1vdmVkMFUw

EwYHKoZIzj0CAQYIKoZIzj0DAQQDPgAEFXHeoI+jd/GHUbdGk/K9BsNkpAMce9AF

DOzYcsoFYFnUyH5O7apm3jGu89b67m1htmzLC4I3AJPsSgUqo2MwYTAPBgNVHRMB

Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBNjAdBgNVHQ4EFgQURoQKwgEzI0rLbwHh

aykbLkF280QwHwYDVR0jBBgwFoAURoQKwgEzI0rLbwHhaykbLkF280QwCgYIKoZI

zj0EAwIDQwAwQAIefcAQYSSqCtoE1waIgQijyZZOC7b3DFub8KP/i4lYAh5ckkpU

cJgDR4UOjk/oa9PSc3I51q/Pv2T9PLoZdeI=

-----END CERTIFICATE-----

 

  Last, obviously, when the keypair is generated in a soft way, by BC, everything works fine.

 

Thanks in advance for your ideas and answers

Éric

 

 

De : Eric Tournier [mailto:[hidden email]]
Envoyé : vendredi 13 décembre 2019 09:47
À : '[hidden email]' <[hidden email]>; [hidden email]
Objet : RE: [dev-crypto] Prime239v1 self-signed certificate cannot be verified

 

Hi everybody

 

  Thanks for the answer, David

  In fact OpenSSL is the only one which seems to verify the certificate without throwing an error, with the following:

#openssl verify -CAfile prime239v1.cer prime239v1.cer

  As I’m not an OpenSSL guru, I don’t know if it is lying or not. In fact both BC and SUN say that they cannot verify my self-signed certificate with its own public key

 

  I’ll try to sign something with the private key (which is in our HSM) and then verifying it. Then I go back here with the results

 

Éric

 

De : David Hook [[hidden email]]
Envoyé : jeudi 12 décembre 2019 01:56
À : [hidden email]
Objet : Re: [dev-crypto] Prime239v1 self-signed certificate cannot be verified

 

 

It looks alright to me as well. How are you verifying it in openSSL though? I've played around with the openssl verify command and it seems I can get it to print OK in a number of situations where I would not have expected it. Something clearly is not right here. Have you tried using java to sign a short message and then verify it? That would at least tell us if it's the signature or the certificate encoding that is the issue.

 

Regards,

 

David

 

 

Reply | Threaded
Open this post in threaded view
|

Re: Prime239v1 self-signed certificate cannot be verified

David Hook-3

Hi Eric,

Assuming the normal text signing hasn't resulted in anything weird, I'd say the public key in the certificate is not the one for the private key. I'd suggest regenerating them to check, it sounds like something is out of sync.

Regards,

David

On 17/12/19 12:51 am, Eric Tournier wrote:

Hi,

 

  I tried to sign some text data after issuing a ECDSA prime239v1 certificate. The verification fails, here is the following code:

        Signature ecdsaVerify = Signature.getInstance("SHA256withECDSA", BouncyCastleProvider.PROVIDER_NAME);

        ecdsaVerify.initVerify(certificate.getPublicKey());

        ecdsaVerify.update(plaintext.getBytes("UTF-8"));

        boolean isValidSignature = ecdsaVerify.verify(Base64.decode(signatureAsString));

 

  The verification of my self-signed certificate with its own private key fails in this part of BC code (org.bouncycastle.crypto.signers.ECDSASigner):

        ECCurve curve = point.getCurve();

        if (curve != null)

        {

            BigInteger cofactor = curve.getCofactor();

            if (cofactor != null && cofactor.compareTo(EIGHT) <= 0)

            {

                ECFieldElement D = getDenominator(curve.getCoordinateSystem(), point);

                if (D != null && !D.isZero())

                {

                    ECFieldElement X = point.getXCoord();

                    while (curve.isValidFieldElement(r))

                    {

                        ECFieldElement R = curve.fromBigInteger(r).multiply(D);

                        if (R.equals(X))

                        {

                            return true;

                        }

                        r = r.add(n);

                    }

                    return false;

                }

            }

        }

 

  The debug shows that in the inner while, we cannot find any ECFieldEleement R which is equal to X. As I haven’t any idea of what it means (I have to work on mathematical basis of ECDSA) :D I need some help :)

  The offending certificate is (Base64 format):

-----BEGIN CERTIFICATE-----

MIIBljCCAUGgAwIBAgISESE/0HMzJQ81M17SAVeO0cQmMAoGCCqGSM49BAMCMB0x

GzAZBgNVBAMMEkhTU1Rlc3RUb0JlUmVtb3ZlZDAgFw0xOTA5MDEwMDAwMDFaGA8y

MDU0MDkwMTAwMDAwMVowHTEbMBkGA1UEAwwSSFNTVGVzdFRvQmVSZW1vdmVkMFUw

EwYHKoZIzj0CAQYIKoZIzj0DAQQDPgAEFXHeoI+jd/GHUbdGk/K9BsNkpAMce9AF

DOzYcsoFYFnUyH5O7apm3jGu89b67m1htmzLC4I3AJPsSgUqo2MwYTAPBgNVHRMB

Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBNjAdBgNVHQ4EFgQURoQKwgEzI0rLbwHh

aykbLkF280QwHwYDVR0jBBgwFoAURoQKwgEzI0rLbwHhaykbLkF280QwCgYIKoZI

zj0EAwIDQwAwQAIefcAQYSSqCtoE1waIgQijyZZOC7b3DFub8KP/i4lYAh5ckkpU

cJgDR4UOjk/oa9PSc3I51q/Pv2T9PLoZdeI=

-----END CERTIFICATE-----

 

  Last, obviously, when the keypair is generated in a soft way, by BC, everything works fine.

 

Thanks in advance for your ideas and answers

Éric

 

 

De : Eric Tournier [[hidden email]]
Envoyé : vendredi 13 décembre 2019 09:47
À : '[hidden email]' [hidden email]; [hidden email]
Objet : RE: [dev-crypto] Prime239v1 self-signed certificate cannot be verified

 

Hi everybody

 

  Thanks for the answer, David

  In fact OpenSSL is the only one which seems to verify the certificate without throwing an error, with the following:

#openssl verify -CAfile prime239v1.cer prime239v1.cer

  As I’m not an OpenSSL guru, I don’t know if it is lying or not. In fact both BC and SUN say that they cannot verify my self-signed certificate with its own public key

 

  I’ll try to sign something with the private key (which is in our HSM) and then verifying it. Then I go back here with the results

 

Éric

 

De : David Hook [[hidden email]]
Envoyé : jeudi 12 décembre 2019 01:56
À : [hidden email]
Objet : Re: [dev-crypto] Prime239v1 self-signed certificate cannot be verified

 

 

It looks alright to me as well. How are you verifying it in openSSL though? I've played around with the openssl verify command and it seems I can get it to print OK in a number of situations where I would not have expected it. Something clearly is not right here. Have you tried using java to sign a short message and then verify it? That would at least tell us if it's the signature or the certificate encoding that is the issue.

 

Regards,

 

David