what padding strategy is used by SunJCE SHA1WithRS

2019-07-23 07:48发布

问题:

Normally both PSS and PKCS1v15 can be used for RSA signatures padding.
And for java the code is also simple, but it just can't tell the padding strategy used.
My code:

Signature signature = Signature.getInstance("SHA1WithRSA");
signature.initSign(privateKey);
signature.update(plainBytes);
byte[] signBytes = signature.sign(); 

May I explicitly define PSS with MGF1 as the padding strategy using SunJCE as provider?

回答1:

PSS is not present in the supported algorithms list of SunJCE. However SHA256withRSA/PSS is implemented in android.

I suggest to use BouncyCastle

Security.addProvider(new BouncyCastleProvider());

Signature sig = Signature.getInstance("SHA1withRSA/PSS");
sig.initSign(privateKey);
sig.update(data);
byte[] signature = sig.sign();

UPDATED

The default maskGenAlgorithm in PKCS#1 v2.1 is MGF1.

RSASSA-PSS-params ::= SEQUENCE {
   hashAlgorithm      [0] OAEP-PSSDigestAlgorithms  DEFAULT sha1,
   maskGenAlgorithm   [1] PKCS1MGFAlgorithms  DEFAULT mgf1SHA1,
   saltLength         [2] INTEGER  DEFAULT 20,
   trailerField       [3] INTEGER  DEFAULT 1
 }

I assume BouncyCastle is using it. You can define your own PSS parameters. For example (see PSSParameterSpec)

sig.setParameter(PSSParameterSpec.DEFAULT);


回答2:

Inspired by the answer, just to add a snippet that shows how to set all the params manually, and of course BouncyCastle has to be used:

Signature signature = Signature.getInstance("SHA256WithRSA/PSS", "BC"); //second param "BC" is not really required
MGF1ParameterSpec mgf1ParameterSpec = new MGF1ParameterSpec("SHA-256"); 
PSSParameterSpec pssParameterSpec = new PSSParameterSpec("SHA-256", "MGF1", mgf1ParameterSpec , 20, 1);
signature.setParameter(pssParameterSpec);
signature.initSign(privateKey);
signature.update(plainBytes);
byte[] signBytes = signature.sign();


回答3:

thanks @xuanzhui

Here is how I successfully verified my (hex encoded) signature:

public static boolean verify(String plainText, String signature, PublicKey publicKey) throws Exception {
    Signature publicSignature = Signature.getInstance("SHA512withRSA/PSS");
    publicSignature.setParameter(new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512 , 64, 1));
    publicSignature.initVerify(publicKey);
    publicSignature.update(plainText.getBytes(UTF_8));

    return publicSignature.verify(hexToBytes(signature));
}

Note despite the documentation suggesting otherwise (getSaltLength() - "returns the salt length in bits") salt length seems to be in bytes!

Also I think "SHA512withRSA/PSS" is only supported from Android 23+