Discussion:
Is Bouncy Castle SHA256withRSA/PSS compatible with OpenSSL RSA PSS padding with SHA256 digest?
Fang Wang
2014-03-12 07:15:36 UTC
Permalink
Hi,

Does anyone know how to verify signature created by OpenSSL (with RSASSA_PSS algorithm) in Java? The default Java Crypto lib does not seem to support PSS padding. I tried Bouncy Castle (with "SHA256withRSA/PSS" algorithm) w/o a success. With OpenSSL, what I did was as following: 
- Initialize: EVP_PKEY_sign_init 
- Set padding: EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) 
- Create digest/hash 
- Sign the hash: EVP_PKEY_sign 

In Bouncy Castle (BC), I did the following: 
        byte[] signature = Base64.decodeBase64(sigText); 
        Base64 base64 = new Base64(); 
        byte [] decoded = base64.decode(publicKeyPEM); 

        X509EncodedKeySpec spec = new X509EncodedKeySpec(decoded); 
        KeyFactory kf = KeyFactory.getInstance("RSA", "BC"); 
        PublicKey key = kf.generatePublic(spec); 

        Signature ss = Signature.getInstance("SHA256withRSA/PSS", "BC"); 
        AlgorithmParameters pss1 = ss.getParameters(); 
        PSSParameterSpec spec1 = new PSSParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), 32, 1); 
        ss.setParameter(spec1); 
        ss.initVerify(key); 
        ss.update(rawData.getBytes()); 
        boolean result = ss.verify(signature); 
I tried different parameters for PSSParameterSpec without a success. Did I do anything wrong with the algorithms or parameters? 

Thanks!
daniel fitzpatrick
2014-03-13 16:02:00 UTC
Permalink
I haven't checked but the problem might be the final parameter in
PSSParameterSpec. This is the value of the trailer field (not its length)
which in PKCS1 should be 0xbc. I'm assuming that's what OpenSSL uses.

Daniel
Post by Fang Wang
Hi,
Does anyone know how to verify signature created by OpenSSL (with
RSASSA_PSS algorithm) in Java? The default Java Crypto lib does not seem to
support PSS padding. I tried Bouncy Castle (with "SHA256withRSA/PSS"
- Initialize: EVP_PKEY_sign_init
- Set padding: EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING)
- Create digest/hash
- Sign the hash: EVP_PKEY_sign
byte[] signature = Base64.decodeBase64(sigText);
Base64 base64 = new Base64();
byte [] decoded = base64.decode(publicKeyPEM);
X509EncodedKeySpec spec = new X509EncodedKeySpec(decoded);
KeyFactory kf = KeyFactory.getInstance("RSA", "BC");
PublicKey key = kf.generatePublic(spec);
Signature ss = Signature.getInstance("SHA256withRSA/PSS", "BC");
AlgorithmParameters pss1 = ss.getParameters();
PSSParameterSpec spec1 = new PSSParameterSpec("SHA-256", "MGF1",
new MGF1ParameterSpec("SHA-256"), 32, 1);
ss.setParameter(spec1);
ss.initVerify(key);
ss.update(rawData.getBytes());
boolean result = ss.verify(signature);
I tried different parameters for PSSParameterSpec without a success. Did I
do anything wrong with the algorithms or parameters?
Thanks!
Dr Stephen N Henson
2014-03-13 16:13:46 UTC
Permalink
Post by Fang Wang
Hi,
Does anyone know how to verify signature created by OpenSSL (with RSASSA_PSS
algorithm) in Java? The default Java Crypto lib does not seem to support PSS
padding. I tried Bouncy Castle (with "SHA256withRSA/PSS" algorithm) w/o a
- Initialize: EVP_PKEY_sign_init
- Set padding: EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING)
- Create digest/hash
- Sign the hash: EVP_PKEY_sign
Make sure the salt lengths are the same. OpenSSL by default uses the maximum
possible salt length when signing and attempts to auto detect the salt length
when verifying. You can use EVP_PKEY_CTX_set_rsa_pss_saltlen to modify that.

Steve.
--
Dr Stephen N. Henson.
Core developer of the OpenSSL project: http://www.openssl.org/
Freelance consultant see: http://www.drh-consultancy.co.uk/
Email: shenson-Pqzf/***@public.gmane.org, PGP key: via homepage.
Fang Wang
2014-03-15 02:09:09 UTC
Permalink
Steve, thanks a lot! Yeah, I also figured out the formula used by OpenSSL: modulus size - hash size - 2 after a bunch of tries. I decided to set this on bouncy castle instead.

Cheers!
Sent from my iPhone
Post by Dr Stephen N Henson
Post by Fang Wang
Hi,
Does anyone know how to verify signature created by OpenSSL (with RSASSA_PSS
algorithm) in Java? The default Java Crypto lib does not seem to support PSS
padding. I tried Bouncy Castle (with "SHA256withRSA/PSS" algorithm) w/o a
- Initialize: EVP_PKEY_sign_init
- Set padding: EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING)
- Create digest/hash
- Sign the hash: EVP_PKEY_sign
Make sure the salt lengths are the same. OpenSSL by default uses the maximum
possible salt length when signing and attempts to auto detect the salt length
when verifying. You can use EVP_PKEY_CTX_set_rsa_pss_saltlen to modify that.
Steve.
--
Dr Stephen N. Henson.
Core developer of the OpenSSL project: http://www.openssl.org/
Freelance consultant see: http://www.drh-consultancy.co.uk/
Fang Wang
2014-03-15 02:21:43 UTC
Permalink
BTW, does Bouncy-Castle support auto detection of the salt length somehow? Having to assume the default setting for OpenSSL is inconvenient. Thanks!
Post by Fang Wang
Steve, thanks a lot! Yeah, I also figured out the formula used by OpenSSL: modulus size - hash size - 2 after a bunch of tries. I decided to set this on bouncy castle instead.
Cheers!
Sent from my iPhone
Post by Dr Stephen N Henson
Post by Fang Wang
Hi,
Does anyone know how to verify signature created by OpenSSL (with RSASSA_PSS
algorithm) in Java? The default Java Crypto lib does not seem to support PSS
padding. I tried Bouncy Castle (with "SHA256withRSA/PSS" algorithm) w/o a
- Initialize: EVP_PKEY_sign_init
- Set padding: EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING)
- Create digest/hash
- Sign the hash: EVP_PKEY_sign
Make sure the salt lengths are the same. OpenSSL by default uses the maximum
possible salt length when signing and attempts to auto detect the salt length
when verifying. You can use EVP_PKEY_CTX_set_rsa_pss_saltlen to modify that.
Steve.
--
Dr Stephen N. Henson.
Core developer of the OpenSSL project: http://www.openssl.org/
Freelance consultant see: http://www.drh-consultancy.co.uk/
David Hook
2014-03-16 02:42:20 UTC
Permalink
Unfortunately not - you need to know the salt length up front before
verifying a PSS signature. It's actually one of the signature algorithm
parameters.

Regards,

David
Post by Fang Wang
BTW, does Bouncy-Castle support auto detection of the salt length somehow? Having to assume the default setting for OpenSSL is inconvenient. Thanks!
Post by Fang Wang
Steve, thanks a lot! Yeah, I also figured out the formula used by OpenSSL: modulus size - hash size - 2 after a bunch of tries. I decided to set this on bouncy castle instead.
Cheers!
Sent from my iPhone
Post by Dr Stephen N Henson
Post by Fang Wang
Hi,
Does anyone know how to verify signature created by OpenSSL (with RSASSA_PSS
algorithm) in Java? The default Java Crypto lib does not seem to support PSS
padding. I tried Bouncy Castle (with "SHA256withRSA/PSS" algorithm) w/o a
- Initialize: EVP_PKEY_sign_init
- Set padding: EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING)
- Create digest/hash
- Sign the hash: EVP_PKEY_sign
Make sure the salt lengths are the same. OpenSSL by default uses the maximum
possible salt length when signing and attempts to auto detect the salt length
when verifying. You can use EVP_PKEY_CTX_set_rsa_pss_saltlen to modify that.
Steve.
--
Dr Stephen N. Henson.
Core developer of the OpenSSL project: http://www.openssl.org/
Freelance consultant see: http://www.drh-consultancy.co.uk/
Uri Blumenthal
2014-03-16 02:45:02 UTC
Permalink
It looks like methods

ECCurve.createPoint(BigInteger x, BigInteger y, boolean compress)
ECPoint.getX()
ECPoint.getY()

are deprecated.

I’d like to strongly urge the developers to not deprecate these methods, as they are very useful to those (like me) who occasionally need to do direct arithmetics.

If there is a better alternative that should be employed instead - please feel free to educate me.

Thanks!
David Hook
2014-03-17 03:07:12 UTC
Permalink
getX() and getY() have been deprecated in favour of methods that allow
for user controlled normalization of the point (they normalize
automatically) so that the normalization operation can be postponed.

getXCoord() will return the x value without normalizing. As the JavaDoc
now says this may not return the same value you would expect if the
point was expressed in affine coordinates.

getAffineXCoord() will return the x value if it is normalized, throwing
an exception if it's not.

The call normalize() will return a normalized version of the point and
getX() is just this.normalize().getXCoord() (likewise so if getY(), so
if you need both it will be more expensive than normalizing the point
first and then getting the values, so you can get the same result as
getX() and getY() with one less normalisation step by saying:

q = q.normalize();
x = q.getXCoord();
y = q.getYCoord();

So the reason for the change is to encourage people to use
getXCoord()/getYCoord() until there is some benefit in using affine
coordinates and then normalize and use
getAffineXCoord()/getAffineYCoord() when it's important that they are.

With ECCurve.createPoint() use ECCurve.createPoint(BigInteger x,
BigInteger y) then turn on point compressing when calling
getEncoded(compressed) if required. This one is more of an
implementation nit. Whether or not a point should be compressed should
really be delayed until the decision is made to encode it - it was done
this way originally due to an earlier implementation of BC's X.509
handling classes, one of those it seemed like a good idea at the time
things...

Regards,

David
Post by Uri Blumenthal
It looks like methods
ECCurve.createPoint(BigInteger x, BigInteger y, boolean compress)
ECPoint.getX()
ECPoint.getY()
are deprecated.
I’d like to strongly urge the developers to not deprecate these methods, as they are very useful to those (like me) who occasionally need to do direct arithmetics.
If there is a better alternative that should be employed instead - please feel free to educate me.
Thanks!
Loading...