I want to make SHA256withRSA/PSS signature in 2 steps, first i hash a message and then sign the digest with RSASSA-PSS
byte[] document = {0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1};
MessageDigest digestor256 = MessageDigest.getInstance("SHA256", "BC");
byte[] documentDigest256 = digestor256.digest(document);
DigestAlgorithmIdentifierFinder hashAlgorithmFinder = new faultDigestAlgorithmIdentifierFinder();
AlgorithmIdentifier hashingAlgorithmIdentifier256 = hashAlgorithmFinder.find("SHA256");
DigestInfo digestInfo2 = new DigestInfo(hashingAlgorithmIdentifier256, documentDigest256);
Signature s2 = Signature.getInstance("NONEwithRSASSA-PSS", "BC");
MGF1ParameterSpec mgfParam = new MGF1ParameterSpec("SHA256");
PSSParameterSpec pssParam = new PSSParameterSpec("SHA256", "MGF1", mgfParam, 32, 1);
s.setParameter(pssParam);
s.initSign(keyPair.getPrivate());
s.update(digestInfo2.getEncoded());
byte[] signature = s.sign();
But i use SHA256withRSA/PSS can't verify
Signature ver = Signature.getInstance("SHA256withRSA/PSS", "BC");
ver.setParameter(pssParam);
ver.initVerify(keyPair.getPublic());
ver.update(document);
boolean re = ver.verify(signature);
I need some help to make it, thank you for your help.
Don't do the DigestInfo. RSASSA-PKCS1v1_5 signatures use the step of encoding the hash in an ASN.1 DER DigestInfo, but RSASSA-PSS signatures do not; see RFC 3447 or 8017. Also you don't need to specify the parameters on the version using the combined algorithm, because the defaults are already correct, although it doesn't hurt to do so redundantly. Example modified to use my keypair, and output to console:
KeyStore ks = KeyStore.getInstance("jks"); ks.load(new FileInputStream(args[0]), args[1].toCharArray());
PrivateKey prv = (PrivateKey)ks.getKey(args[2], args[1].toCharArray());
PublicKey pub = ks.getCertificate(args[2]).getPublicKey();
byte[] document = {0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1};
MessageDigest digestor256 = MessageDigest.getInstance("SHA256", "BC");
byte[] documentDigest256 = digestor256.digest(document);
Signature s2 = Signature.getInstance("NONEwithRSASSA-PSS", "BC");
MGF1ParameterSpec mgfParam = new MGF1ParameterSpec("SHA256");
PSSParameterSpec pssParam = new PSSParameterSpec("SHA256", "MGF1", mgfParam, 32, 1);
s2.setParameter(pssParam);
s2.initSign(prv);
s2.update(documentDigest256);
byte[] signature = s2.sign();
Signature ver = Signature.getInstance("SHA256withRSA/PSS", "BC");
if(false){ ver.setParameter(pssParam); } // can enable if desired
ver.initVerify(pub);
ver.update(document);
System.out.println( ver.verify(signature) );
Also, trivially, you had misspelled DefaultDigestAlgorithmIdentifierFinder
and used s2
vs s
for the variable name.