Fix various bugs and issues in crypto/elytron (#23102)

closes #23173
This commit is contained in:
David Anderson 2023-10-03 02:42:57 -05:00 committed by GitHub
parent fbae2251e1
commit ceea11d044
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 286 additions and 55 deletions

View file

@ -37,6 +37,7 @@ import java.util.List;
import javax.security.auth.x500.X500Principal;
import org.jboss.logging.Logger;
import org.keycloak.common.crypto.CertificateUtilsProvider;
import org.wildfly.security.asn1.ASN1;
import org.wildfly.security.asn1.DERDecoder;
@ -60,6 +61,8 @@ import org.wildfly.security.x500.cert.X509CertificateExtension;
*/
public class ElytronCertificateUtils implements CertificateUtilsProvider {
Logger log = Logger.getLogger(getClass());
/**
* Generates version 3 {@link java.security.cert.X509Certificate}.
*
@ -249,16 +252,29 @@ public class ElytronCertificateUtils implements CertificateUtilsProvider {
case ASN1.UTF8_STRING_TYPE:
distPointUrls.add(der.decodeUtf8String());
break;
case 0xa0:
der.decodeImplicit(0xa0);
byte[] edata = der.decodeOctetString();
while(!Character.isLetterOrDigit(edata[0])) {
edata = Arrays.copyOfRange(edata, 1, edata.length);
}
distPointUrls.add(new String(edata));
case 0xa0: // Decode CRLDistributionPoint FullName list
der.startExplicit(0xa0);
break;
case 0x86: // Decode CRLDistributionPoint FullName
der.decodeImplicit(0x86);
distPointUrls.add(der.decodeOctetStringAsString());
log.debug("Adding Dist point name: " + distPointUrls.get(distPointUrls.size()-1));
break;
default:
der.skipElement();
}
// Check to see if there is another sequence to process
try {
if(!der.hasNextElement() && der.peekType() == ASN1.SEQUENCE_TYPE) {
der.startSequence();
} else if (!der.hasNextElement() && der.peekType() == 0xa0) {
der.startExplicit(0xa0);
}
} catch(Exception e) {
// Just log this error. Likely the Dist points have been parsed, but
// the end of the cert is failing to parse.
log.warn("There is an issue parsing the certificate for Distribution Points", e);
}
}

View file

@ -19,6 +19,7 @@ package org.keycloak.crypto.elytron;
import java.io.IOException;
import java.math.BigInteger;
import org.jboss.logging.Logger;
import org.keycloak.common.crypto.ECDSACryptoProvider;
import org.wildfly.security.asn1.DERDecoder;
import org.wildfly.security.asn1.DEREncoder;
@ -28,6 +29,8 @@ import org.wildfly.security.asn1.DEREncoder;
*/
public class ElytronECDSACryptoProvider implements ECDSACryptoProvider {
Logger log = Logger.getLogger(getClass());
@Override
public byte[] concatenatedRSToASN1DER(final byte[] signature, int signLength) throws IOException {
int len = signLength / 2;
@ -45,6 +48,7 @@ public class ElytronECDSACryptoProvider implements ECDSACryptoProvider {
seq.startSequence();
seq.encodeInteger(rBigInteger);
seq.encodeInteger(sBigInteger);
seq.endSequence();
return seq.getEncoded();
@ -56,13 +60,35 @@ public class ElytronECDSACryptoProvider implements ECDSACryptoProvider {
DERDecoder der = new DERDecoder(derEncodedSignatureValue);
der.startSequence();
byte[] r = der.decodeInteger().toByteArray();
byte[] s = der.decodeInteger().toByteArray();
byte[] r = convertToBytes(der.decodeInteger(),len);
byte[] s = convertToBytes(der.decodeInteger(),len);
der.endSequence();
byte[] concatenatedSignatureValue = new byte[signLength];
System.arraycopy(r, 0, concatenatedSignatureValue, 0, len);
System.arraycopy(s, 0, concatenatedSignatureValue, len, len);
return concatenatedSignatureValue;
}
// If byte array length doesn't match expected length, copy to new
// byte array of the expected length
private byte[] convertToBytes(BigInteger decodeInteger, int len) {
byte[] bytes = decodeInteger.toByteArray();
if(len < bytes.length) {
log.debug("Decoded integer byte length greater than expected.");
byte[] t = new byte[len];
System.arraycopy(bytes, bytes.length - len, t, 0, len);
bytes = t;
} else if (len > bytes.length) {
log.debug("Decoded integer byte length less than expected.");
byte[] t = new byte[len];
System.arraycopy(bytes, 0, t, len - bytes.length, bytes.length);
bytes = t;
}
return bytes;
}
}

View file

@ -16,24 +16,42 @@
*/
package org.keycloak.crypto.elytron;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CRLReason;
import java.security.cert.CertPath;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertPathBuilderException;
import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorResult;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.PKIXCertPathValidatorResult;
import java.security.cert.PKIXParameters;
import java.security.cert.PKIXRevocationChecker;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Date;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.net.ssl.TrustManagerFactory;
import org.jboss.logging.Logger;
import org.keycloak.common.util.PemUtils;
import org.keycloak.models.KeycloakSession;
import org.keycloak.utils.OCSPProvider;
import org.wildfly.security.asn1.ASN1;
@ -61,27 +79,42 @@ public class ElytronOCSPProvider extends OCSPProvider {
* @throws CertPathValidatorException
*/
@Override
protected OCSPRevocationStatus check(KeycloakSession session, X509Certificate cert, X509Certificate issuerCertificate, List<URI> responderURIs, X509Certificate responderCert, Date date) throws CertPathValidatorException {
protected OCSPRevocationStatus check(KeycloakSession session, X509Certificate cert,
X509Certificate issuerCertificate, List<URI> responderURIs, X509Certificate responderCert, Date date)
throws CertPathValidatorException {
if (responderURIs == null || responderURIs.size() == 0)
throw new IllegalArgumentException("Need at least one responder");
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null,"pass".toCharArray());
trustStore.setCertificateEntry("trust", cert);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustStore.load(null, "pass".toCharArray());
trustStore.setCertificateEntry("trust", issuerCertificate);
X509RevocationTrustManager trustMgr = X509RevocationTrustManager.builder()
.setOcspResponderCert(responderCert)
.setTrustStore(trustStore)
.setTrustManagerFactory(trustManagerFactory)
.build()
;
CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
PKIXRevocationChecker rc = (PKIXRevocationChecker) cpb.getRevocationChecker();
X509CertSelector certSelector = new X509CertSelector();
X509Certificate[] certs = { cert };
trustMgr.checkClientTrusted(certs, cert.getType());
} catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException e) {
certSelector.setCertificate(cert);
certSelector.setCertificateValid(date);
CertPath cp = cf.generateCertPath(Arrays.asList(certs));
PKIXParameters params = new PKIXBuilderParameters(trustStore, certSelector);
rc.setOcspResponder(responderURIs.get(0));
rc.setOcspResponderCert(responderCert);
rc.setOptions(EnumSet.noneOf(PKIXRevocationChecker.Option.class));
params.setRevocationEnabled(false);
params.addCertPathChecker(rc);
PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv.validate(cp, params);
logger.debug("Certificate validated by CA: " + result.getTrustAnchor().getCAName());
} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | CertificateException | IOException
| KeyStoreException e) {
logger.warn("OSCP Response check failed.", e);
return unknownStatus();
}
@ -155,6 +188,7 @@ public class ElytronOCSPProvider extends OCSPProvider {
}
}
logger.warn("OCSP Responder URIs" + Arrays.toString(responderURIs.toArray()));
return responderURIs;
}
}

View file

@ -39,7 +39,7 @@ import org.wildfly.security.x500.principal.X500AttributePrincipalDecoder;
*/
public class ElytronUserIdentityExtractorProvider extends UserIdentityExtractorProvider {
private static final Logger logger = Logger.getLogger(ElytronUserIdentityExtractorProvider.class.getName());
private Logger log = Logger.getLogger(this.getClass());
class X500NameRDNExtractorElytronProvider extends X500NameRDNExtractor {
@ -47,8 +47,13 @@ public class ElytronUserIdentityExtractorProvider extends UserIdentityExtractor
Function<X509Certificate[],Principal> x500Name;
public X500NameRDNExtractorElytronProvider(String attrName, Function<X509Certificate[], Principal> x500Name) {
//this.x500NameStyle = BCStyle.INSTANCE.attrNameToOID(attrName);
// The OidsUtil fails to map 'EmailAddress', instead 'E' is mapped to the OID.
// TODO: Open an issue with wildfly-elytron to include 'EmailAddress' in the oid mapping
if(attrName.equals("EmailAddress")) {
attrName = "E";
}
this.x500NameStyle = OidsUtil.attributeNameToOid(OidsUtil.Category.RDN, attrName);
log.debug("Attribute Name: " + attrName + " X500NameStyle OID: " + x500NameStyle);
this.x500Name = x500Name;
}
@ -59,6 +64,7 @@ public class ElytronUserIdentityExtractorProvider extends UserIdentityExtractor
throw new IllegalArgumentException();
Principal name = x500Name.apply(certs);
log.debug("Principal Name " + name.getName());
X500AttributePrincipalDecoder xDecoder = new X500AttributePrincipalDecoder(x500NameStyle);
String cn = xDecoder.apply(name);
@ -95,13 +101,14 @@ public class ElytronUserIdentityExtractorProvider extends UserIdentityExtractor
}
String subjectName = null;
logger.info("SubjPrinc " + certs[0].getSubjectX500Principal());
log.debug("SubjPrinc " + certs[0].getSubjectX500Principal());
Collection<List<?>> subjectAlternativeNames;
try {
subjectAlternativeNames = certs[0].getSubjectAlternativeNames();
if (subjectAlternativeNames == null) {
return null;
}
log.info(Arrays.toString(subjectAlternativeNames.toArray()));
for (List<?> sbjAltName : subjectAlternativeNames) {
if (sbjAltName == null)
continue;
@ -109,15 +116,13 @@ public class ElytronUserIdentityExtractorProvider extends UserIdentityExtractor
Integer nameType = (Integer) sbjAltName.get(0);
if (nameType == generalName) {
logger.info("sbjAltName Type " + nameType);
logger.info("sbjAltName[1]: " + sbjAltName.get(1));
Object sbjObj = sbjAltName.get(1);
switch (nameType) {
case GeneralName.RFC_822_NAME:
case GeneralName.DNS_NAME:
case GeneralName.DIRECTORY_NAME:
case GeneralName.URI_NAME:
subjectName = (String) sbjObj;
break;
case GeneralName.OTHER_NAME:
@ -126,12 +131,12 @@ public class ElytronUserIdentityExtractorProvider extends UserIdentityExtractor
boolean upnOidFound = false;
while (derDecoder.hasNextElement() && !upnOidFound) {
int asn1Type = derDecoder.peekType();
logger.info("ASN.1 Type: " + derDecoder.peekType());
log.debug("ASN.1 Type: " + derDecoder.peekType());
switch (asn1Type) {
case ASN1.OBJECT_IDENTIFIER_TYPE:
String oid = derDecoder.decodeObjectIdentifier();
logger.info("OID: " + oid);
log.debug("OID: " + oid);
if(UPN_OID.equals(oid)) {
derDecoder.decodeImplicit(160);
byte[] sb = derDecoder.drainElementValue();
@ -154,22 +159,28 @@ public class ElytronUserIdentityExtractorProvider extends UserIdentityExtractor
case ASN1.OCTET_STRING_TYPE:
subjectName = derDecoder.decodeOctetStringAsString();
break;
case 0xa0:
derDecoder.startExplicit(asn1Type);
break;
case ASN1.SEQUENCE_TYPE:
derDecoder.startSequence();
default:
derDecoder.skipElement();
}
}
logger.info("Subject Alt Name: " + subjectName);
}
}
}
} catch (CertificateParsingException | UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
log.error("Failed to parse Subject Name:",e);
}
log.debug("Subject Alt Name: " + subjectName);
return subjectName;
}
}

View file

@ -18,18 +18,22 @@ package org.keycloak.crypto.elytron.test;
import static org.junit.Assert.assertArrayEquals;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import javax.security.auth.x500.X500Principal;
import org.junit.Test;
import org.keycloak.common.util.PemUtils;
import org.keycloak.crypto.elytron.ElytronCertificateUtils;
import org.wildfly.security.x500.GeneralName;
import org.wildfly.security.x500.cert.CRLDistributionPoint;
@ -46,9 +50,9 @@ public class CRLDistributionPointTest {
@Test
public void getCrlDistPoint() throws CertificateException, NoSuchAlgorithmException, IOException {
X509Certificate cert = createCRLcert();
X509Certificate cert = createCRLcert(1,1);
List<String> expect = new ArrayList<>();
expect.add("http://crl.test.com");
expect.add("http://crl0.test0.com");
ElytronCertificateUtils bcutil = new ElytronCertificateUtils();
@ -58,16 +62,67 @@ public class CRLDistributionPointTest {
}
private X509Certificate createCRLcert() throws CertificateException, NoSuchAlgorithmException {
@Test
public void getCrlDistPointMultiNames() throws CertificateException, NoSuchAlgorithmException, IOException {
X509Certificate cert = createCRLcert(1,2);
List<String> expect = new ArrayList<>();
expect.add("http://crl0.test0.com");
expect.add("http://crl0.test1.com");
ElytronCertificateUtils bcutil = new ElytronCertificateUtils();
List<String> crldp = bcutil.getCRLDistributionPoints(cert);
assertArrayEquals(expect.toArray(), crldp.toArray());
}
@Test
public void getMultiCrlDistPointMultiNames() throws CertificateException, NoSuchAlgorithmException, IOException {
X509Certificate cert = createCRLcert(2,2);
List<String> expect = new ArrayList<>();
expect.add("http://crl0.test0.com");
expect.add("http://crl0.test1.com");
expect.add("http://crl1.test0.com");
expect.add("http://crl1.test1.com");
ElytronCertificateUtils bcutil = new ElytronCertificateUtils();
List<String> crldp = bcutil.getCRLDistributionPoints(cert);
assertArrayEquals(expect.toArray(), crldp.toArray());
}
@Test
public void revokedCertCRLDistTest() throws CertificateException, IOException {
X509Certificate cert = revokedCert();
List<String> expect = new ArrayList<>();
expect.add("http://localhost:8889/empty.crl");
expect.add("http://localhost:8889/intermediate-ca.crl");
ElytronCertificateUtils bcutil = new ElytronCertificateUtils();
List<String> crldp = bcutil.getCRLDistributionPoints(cert);
assertArrayEquals(expect.toArray(), crldp.toArray());
}
private X509Certificate createCRLcert(int crldistcount, int namecount) throws CertificateException, NoSuchAlgorithmException {
X500Principal dn = new X500Principal("CN=testuser,OU=UNIT,O=TST");
List<CRLDistributionPoint> distributionPoints = new ArrayList<>();
for(int x = 0; x<crldistcount;x++) {
List<GeneralName> fullName = new ArrayList<>();
fullName.add(new GeneralName.URIName("http://crl.test.com"));
for(int y = 0; y<namecount; y++) {
fullName.add(new GeneralName.URIName("http://crl"+x+".test"+y+".com"));
}
DistributionPointName distributionPoint = new FullNameDistributionPointName(fullName);
CRLDistributionPoint arg0 = new CRLDistributionPoint(distributionPoint, null, null);
distributionPoints.add(arg0);
}
KeyPair keyPair = KeyPairGenerator.getInstance("RSA").genKeyPair();
X509CertificateBuilder cbuilder = new X509CertificateBuilder()
.setSubjectDn(dn)
@ -83,6 +138,16 @@ public class CRLDistributionPointTest {
return cbuilder.build();
}
X509Certificate revokedCert() throws CertificateException {
String certStr = "-----BEGIN CERTIFICATE-----\n" +
"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"
+ "\n-----END CERTIFICATE-----";
CertificateFactory cf = CertificateFactory.getInstance("X.509");
return (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certStr.getBytes()));
}
}

View file

@ -42,9 +42,13 @@ public class ElytronHmacTest extends HmacTest {
SecureRandom random = isWindows() ? SecureRandom.getInstance("Windows-PRNG") : SecureRandom.getInstance("NativePRNG");
random.setSeed(UUID.randomUUID().toString().getBytes());
keygen.init(random);
SecretKey secretKey = keygen.generateKey();
SecretKey secret = keygen.generateKey();
testHMACSignAndVerify(secretKey, "testHmacSignaturesUsingKeyGen");
String encoded = new JWSBuilder().content("12345678901234567890".getBytes())
.hmac256(secret);
System.out.println("length: " + encoded.length());
JWSInput input = new JWSInput(encoded);
Assert.assertTrue(HMACProvider.verify(input, secret));
}
private boolean isWindows(){
return System.getProperty("os.name").startsWith("Windows");

View file

@ -30,8 +30,6 @@ import org.keycloak.common.crypto.CryptoIntegration;
import org.keycloak.common.util.KeystoreUtil;
import org.keycloak.rule.CryptoInitRule;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@ -44,7 +42,7 @@ public class ElytronKeyStoreTypesTest {
@Test
public void testKeystoreFormats() {
Set<KeystoreUtil.KeystoreFormat> supportedKeystoreFormats = CryptoIntegration.getProvider().getSupportedKeyStoreTypes().collect(Collectors.toSet());
assertThat(supportedKeystoreFormats, Matchers.containsInAnyOrder(
Assert.assertThat(supportedKeystoreFormats, Matchers.containsInAnyOrder(
KeystoreUtil.KeystoreFormat.JKS,
KeystoreUtil.KeystoreFormat.PKCS12
));

View file

@ -18,10 +18,14 @@ package org.keycloak.crypto.elytron.test;
import static org.junit.Assert.assertEquals;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import org.junit.ClassRule;
import org.junit.Test;
import org.keycloak.common.crypto.CryptoIntegration;
import org.keycloak.common.crypto.PemUtilsProvider;
import org.keycloak.rule.CryptoInitRule;
public class ElytronPemUtilsTest {
@ -42,5 +46,26 @@ public class ElytronPemUtilsTest {
String encoded = org.keycloak.common.util.PemUtils.generateThumbprint(test, "SHA-256");
assertEquals(43, encoded.length());
}
@Test
public void testenocdedecode() throws NoSuchAlgorithmException, NoSuchProviderException {
PemUtilsProvider pemutil = CryptoIntegration.getProvider().getPemUtils();
KeyPair keypair = CryptoIntegration.getProvider().getKeyPairGen("RSA").generateKeyPair();
String pem = pemutil.encodeKey(keypair.getPrivate());
Object decodekey = pemutil.decodePrivateKey(pem);
}
@Test
public void testtrkey() {
String key = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKtWsK5O0CtuBpnMvWG+HTG0vmZzujQ2o9WdheQu+BzCILcGMsbDW0YQaglpcO5JpGWWhubnckGGPHfdQ2/7nP9QwbiTK0FbGF41UqcvoaCqU1psxoV88s8IXyQCAqeyLv00yj6foqdJjxh5SZ5z+na+M7Y2OxIBVxYRAxWEnfUvAgMBAAECgYB+Y7yBWHIHF2qXGYi6CVvPxtyNBuFcktHYShLyeBNeY3VujYv3QzSZQpJ1zuoXXQuARMHOovyNiVAhu357pMfx9wSkoKNSXKrQx/+9Vt9lI1pXJxjXedPOjbuI/JZAcrk0u4nOfXG/HGtR5cjoDZYWkYQEtsePCnHlZAb0D7axwQJBAO92f00Tvkc9NU/EGqwR3bPXRMqSX0JnG7XRBvLeJBCZYsQn0s2bLdpy8qsTeAyJg1ZvrEc8qIio5HVqzsvbhpMCQQC3K9A6UK+vmQCNWqsQpdqWPRPN7CPB67FzSmyS8CtMjY6jTvSHrkamggotz2N/5QDr1xG2q7A/3dpkq1bTpTx1AkAXZjjiSz+Yrn57IOqKTeSgIjTypoLwdirbBWXsbZCQnqxsBogu1y8P3ZOg6/IbJ4TR+W+YNnExiW9pmdpDSVxJAkEAplTq6YmLf/F4RuQmox94tyUPbtcYQWg942uZ3HSrXQDOng18kBj5nwpHJAJHYEQb6g2K0E5n5hcX0oKkfdx2YQJAcSKAmFiD7KQ6+vVqJlQwVPvYdTSOeZB7YVV6S4b4slS3ZObsa0yNMWgal/QnCtW5k3f185gCWj6dOLGB5btfxg==";
PemUtilsProvider pemutil = CryptoIntegration.getProvider().getPemUtils();
pemutil.decodePrivateKey(key);
}
}

View file

@ -0,0 +1,52 @@
package org.keycloak.crypto.elytron.test;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.PSSParameterSpec;
import org.junit.Test;
import org.keycloak.common.crypto.CryptoIntegration;
import org.keycloak.crypto.JavaAlgorithm;
import org.keycloak.crypto.KeyWrapper;
public class ElytronSignatureAlgTest {
private byte[] data = "Test String to Encrypt".getBytes();
@Test
public void signatureDefaultAlg() throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, InvalidAlgorithmParameterException, InvalidKeySpecException {
KeyPair keyPair = KeyPairGenerator.getInstance("RSASSA-PSS").genKeyPair();
KeyWrapper key = new KeyWrapper();
//key.setPrivateKey(keyPair.getPrivate());
key.setAlgorithm("PS256");
KeySpec kspec = new PKCS8EncodedKeySpec(keyPair.getPrivate().getEncoded());
key.setPrivateKey(KeyFactory.getInstance("RSASSA-PSS").generatePrivate(kspec));
Signature signature = Signature.getInstance("RSASSA-PSS");
MGF1ParameterSpec ps = MGF1ParameterSpec.SHA256;
AlgorithmParameterSpec params = new PSSParameterSpec(ps.getDigestAlgorithm(), "MGF1", ps, 32, 1);
signature.setParameter(params);
signature.initSign(keyPair.getPrivate());
//signature.initSign((PrivateKey) key.getPrivateKey());
signature.update(data);
System.out.println(signature.getProvider() + " Alg ###########");
if(signature.getAlgorithm().equals("RSASSA-PSS")) {
}
signature.sign();
}
}