I want to show that if I modify one bit or byte from a given X509 certificate the signature verification results false (because this modification results different hash value from the certificate). I'm stuck in the case that how to do the modification on the certificate using getTBSCertificate() method. My following code does the verification process perfectly BUT I tried to make it fail using bit or byte modification's idea but it doesn't work. Note that this idea that I proposed is to proof that any modification on the certificate will make a failure while signature verification
public class VerifyX509 {
private static Certificate getCACert;
private static Certificate[] getCert;
public static void main(String[] args) throws CertificateEncodingException {
setURLConnection("https://www.google.com");
X509Certificate x509cert= (X509Certificate) getCert[0];
byte[] b= x509cert.getTBSCertificate();
b[0] = (byte) ~b[0];
// HOW TO UPDATE getTBSCertificate() after flipping the b[0] to make Verify() in my method verifySign() return false!
verifySign();
}
public static void setURLConnection(String link){
try{
int i=1;
URL destinationURL = new URL(link);
HttpsURLConnection con = (HttpsURLConnection) destinationURL.openConnection();
con.connect();
getCert = con.getServerCertificates();
for (Certificate c : getCert)
{
if (i==2)
{
getCACert= c;
return;
}
i+=1;
}
}catch (Exception e1) {
JOptionPane.showMessageDialog(null, "Error while connection! Check your Internet Connection.");
e1.printStackTrace();
}
}
public static boolean verifySign()
{
try
{
getCert[0].verify(getCACert.getPublicKey());
return true;
} catch (GeneralSecurityException e2)
{
return false;
}
}
}
How can I setup proof-of-concept code to show that the verification while fail?
Note that this idea that I proposed is to proof that any modification on the certificate will make a failure while signature verification.
You can demonstrate this (to a certain probability of correctness) by simply flipping random bits in valid certificates and then attempting to validate them.
However, you cannot prove anything like this. A proper proof requires:
A mathematical proof that a properly implement X509 certificate has the property that changing the certificate renders it invalid (with some probability very close to one1).
A formal-methods proof that the code that is loading the certificate and doing the verification is correctly implemented.
1 - In fact, it is easy to see that the probability cannot be exactly one. Apply the pigeonhole principle.
byte[] b= x509cert.getTBSCertificate();
b[0] = (byte) ~b[0];
Changing a byte in an array that you have obtained from the certificate doesn't change the certificate.
You would have to reload it from the byte array using a CertificateFactory.
Mr. Mike, all what you have to do is to get the row data DER-encoded certificate information (TBS part) and you can extract it as below
URL url = new URL("https://www.google.com/");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.connect();
Certificate userCert[] = con.getServerCertificates();
X509Certificate x509cert = ((X509Certificate) userCert[0]);
byte[] tbs=x509cert.getTBSCertificate();
Then copy the content of the array b to another array bcopy through a loop and do what ever modifications you want (i.e by using the masking technique Anding with x55) after that you can get the hash value through
String sha1 = "";
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(bcopy);
sha1 = byteToHex(crypt.digest());
private static String byteToHex(final byte[] hash)
{
Formatter formatter = new Formatter();
for (byte b : hash)
{
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
at this point you have the hash value of the modified certificate, you can go now and extract the signature from the original certificate [ byte[] sig= x509cert.getSignature(); ] and decrypt the signature to get the hash value and compare it with the modified hash value, good luck ;)
If you look at RFC 5280, the cert has 3 fields:
tbsCertificate
signatureAlgorithm
signatureValue
The signatureValue is the very last item in the certificate.
I had a similar requirement. These are the steps I followed:
Have 1 certificate in .crt format (base-64 encoded) file. The cert is enclosed between "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----"
Edit the very last character of the certificate on the line just before the END CERTIFICATE line. Just add 1 to that character or reduce by 1. If the last character is x, make it either y or w.
This will change the signature in the certificate and the signature won't be valid anymore.
Related
Below I have included code that takes a Thumbprint of a certificate as an argument and then loads the appropriate cert from the Windows certificate store.
This was done because now I would like to use the found cert to make API calls to an API that requires this certificate- if the certificate is not included in the request the API will reject me as unauthorized.
I have previously done this in C# and it was quite simple as I was able to just create a clientHandler that identified the protocol, callback, and certificate that allowed for creation of a usable HttpClient. Java is significantly more complicated and is giving me issues since it appears I must work with the keymanager(and possibly trustStore and SSLContext). In other words I am having a hard time understanding how to use these objects to send my certificate to the API with my request.
I realize I may not be able to simply build the client with the cert to get the successful connection. But how can I use the x509certificate that I have in memory to successfully send requests to the API.
I am not looking for a solution that will 100% work for my case, I would just like to see a clean example of how to send an API request with the certificate(in whichever way the libraries require) in Java.
public static X509Certificate LoadCert(String inThumbprint) {
X509Certificate ReturnCert = null;
try{
KeyStore keyStore = KeyStore.getInstance("Windows-MY");
keyStore.load(null, null); // Load keystore
String currentAlias;
X509Certificate foundCert;
String calculatedThumbprint;
for (Enumeration<String> oEnum = keyStore.aliases(); oEnum.hasMoreElements();) {
currentAlias = oEnum.nextElement(); System.out.println(currentAlias);
foundCert = (X509Certificate) keyStore.getCertificate(currentAlias);
calculatedThumbprint = getThumbprint(foundCert); System.out.println(calculatedThumbprint);
if (calculatedThumbprint.equals(inThumbprint)) {
ReturnCert = foundCert;
}
}
} catch (Exception ex){
ex.printStackTrace();
}
return ReturnCert;
}
private static String getThumbprint(X509Certificate cert)
throws NoSuchAlgorithmException, CertificateEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] der = cert.getEncoded();
md.update(der);
byte[] digest = md.digest();
String digestHex = DatatypeConverter.printHexBinary(digest);
return digestHex.toLowerCase();
}
I am using secp256k1 to sign hash of a text in server and verify the signature on client side .
Now, I need to send actual text as well to the client but my main constraint is bandwidth and I can't add text separately. Therefore, I need to be able to put the actual text inside signature and extract it during verification?
Here is my code
Signing
static final X9ECParameters curve = SECNamedCurves.getByName ("secp256k1");
static final ECDomainParameters domain = new ECDomainParameters(curve.getCurve (), curve.getG (), curve.getN (), curve.getH ());
public byte[] sign (byte[] hash) throws CryptoException
{
if ( priv == null )
{
throw new CryptoException (ErrorCode.KEY_NOT_FOUND, "Need private key to sign");
}
ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest()));
signer.init (true, new ECPrivateKeyParameters(priv, domain));
BigInteger[] signature = signer.generateSignature (hash);
ByteArrayOutputStream s = new ByteArrayOutputStream();
try
{
DERSequenceGenerator seq = new DERSequenceGenerator(s);
seq.addObject (new ASN1Integer(signature[0]));
seq.addObject (new ASN1Integer(signature[1]));
seq.close ();
return s.toByteArray ();
}
catch ( IOException e )
{
}
return null;
}
Verification
public static boolean verify (byte[] hash, byte[] signature, byte[] pub)
{
ASN1InputStream asn1 = new ASN1InputStream(signature);
try
{
ECDSASigner signer = new ECDSASigner();
signer.init (false, new ECPublicKeyParameters(curve.getCurve ().decodePoint (pub), domain));
DLSequence seq = (DLSequence) asn1.readObject ();
BigInteger r = ((ASN1Integer) seq.getObjectAt (0)).getPositiveValue ();
BigInteger s = ((ASN1Integer) seq.getObjectAt (1)).getPositiveValue ();
return signer.verifySignature (hash, r, s);
}
catch ( Exception e )
{
// threat format errors as invalid signatures
return false;
}
finally
{
try
{
asn1.close ();
}
catch ( IOException e )
{
}
}
}
ECDSA requires a hash over the message to be secure. So all information is lost. Some signature schemes use a hash + part of the message. This is for instance the case for RSA in the ISO/IEC 9796 signature schemes giving (partial) message recovery - which is the technical term of what you (and Dave Thompson) are talking about.
However ECDSA signatures are just big enough to contain a single hash (and usually not even that); there is not much you can do to add data to the hash value. Trying to use EC signatures for partial message recovery is an exercise in futility (also because how verification is performed).
However if you want to use fewer bits you can do still things:
use the most dense representation of message and signature (e.g. just R and S concatenated for ECDSA signatures);
use the smallest key size possible (check https://keylength.com/ for info);
switch to a signature scheme that uses smaller signatures, for instance the BLS signature scheme over elliptic curves - it will halve the signature size compared to ECDSA (using the most efficient encoding).
I've put the BLS scheme last because it is usually not in generic libraries; I consider it the expert way out. You may hit a learning curve.
Signatures themselves don't compress well, by the way, unless you encode them badly. The other disadvantage of compression is that it is usually tricky to calculate a maximum size for all possible messages.
A digital signature, ECDSA or RSA, generally doesn't contain the message (see #dave_thompson_085 comment). An "attached signature" refers to a file that basically contains the message and the digital signature, which can be encoded in a CMS or XMLDsig format.
So if you need to send the message and the signature, just send them together, using a custom or a known format, and compress it additionally to reduce the size
AttachedSignature = zip(format(message + signature))
I am trying to verify a JWT token by verifying its signature. But during the verification I get an error
java.security.SignatureException: Signature length not correct: got
342 but was expecting 256
. I assume that signature is the encrypted sha256 hash of the data. In my case data is base64(header)+"."+base64(body). Here is my code:
static String certificate = "MIIDBjCCAe4CCQDmPif23IJerzANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMB4XDTE1MDkyMjA3MDkwMFoXDTE2MDkyMTA3MDkwMFowRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALYjKc8pLFkAa45j6w6PHsroe7ijOCfhZmVtMCvZ8lINaP9mR8irOJHpLdJs4vpbxEZMqqLMhKjO7iUmXBmml37QRlJXY6f25essPkTdUmhiIrU/rIrZrCanvegXUHkvf4xvOQ1BTx/p5b1iIq3Wrk5Fox3pMigzqYhk4YuiJho8uabC9zyecmS3zIoRgwx+Vacel/ZW6r6YOlB6mblN9IvasvqWgDalegmMKOIZvwkpo/3mfzcGi5haWZZ3ufUqQjb4B7raJmfyrLnwi6XI9UzzGc04pCfIAsxTb5yM8cJQcJ/5VHF3h21eFJdZKyD2210gSq7/Y8Oda0dDXQchmFcCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAmBm84PfwOe5sGemT9D4ImIYWp/1xrV6b0zeaDZ6Yi7sz9R3VKjfnAxUVOHA7GlMi8xHHdDu7VhVhAWyFCvITdG00K18xJuKap1bwzw3kr70lLQaFahV+zaWKfWAfV34tots3G/hMqdOv0a+I/5t/T7oKPCmm/IfCVKdC1tGbTji+hxVLpaAkn60RFNzLKGFwtSxv9ObxR5Hn88+wV48VAcEnwcUk2DjBi1fW6jnMcNJbVd+/oKBOwj7UK2Lk10Qaeet8KKh5fFKEpgx7D4ITwer0G/Je1NMv1/lfNzpKlTKoBureF5C6B+rJIesQ/dAfg6H/ggxbgVMuo6imIPVvrg==";
static String signedData = "Z5MwwjtXdypMQGNwmNNuCVmRcDVT24EgtwoDWalF4icxwz7jyB99Yg3262D7OsERewv4cOfdEz3bbOF-iG7YWXeSC9YZeO1tGapqlc8FRtAergSUZC7BcbFEx75MfSy7qLWYTOfdpJesQ23rOzjF7KdrAMJC_Y0T_r6RuBcZVyfT4P55kICETYyv7bBDXc9V8BJUf-QHDu6DaH7u6PSyeOmdzFInI_LwySnMlr3VahoUfUpJmauU8yHQUnFakJBgrMBe1Au9tS-HxtDVnHmoHQw8xGXsVQnEOa1aPAcVWy0v7hILUSmWNAG3IZ0JwUztQitgtnTTzXDszUxTbJ4YlQ";
static String data = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSIsImtpZCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSJ9.eyJhdWQiOiJodHRwczovL2NpdHJpeHAuY29tOjg0NDMvIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvZGQ5YjZhM2UtMjlkMS00MjU0LWE3NDYtZTAyOTQxNDQ0NTE3LyIsImlhdCI6MTQ0MjYyNjA0NSwibmJmIjoxNDQyNjI2MDQ1LCJleHAiOjE0NDI2Mjk5NDUsInZlciI6IjEuMCIsInRpZCI6ImRkOWI2YTNlLTI5ZDEtNDI1NC1hNzQ2LWUwMjk0MTQ0NDUxNyIsIm9pZCI6ImJkZDNmZDAyLTEyMzMtNGMxOC05NTRmLWJkNGFjMWYzOWU5OSIsInVwbiI6InNwQGNpdHJpeHAuY29tIiwic3ViIjoieUFfZTFzMmFOeFdvR3NSNzhfVWNYZkk5dERlYUM0QUozdXFZQXFDdllSbyIsImdpdmVuX25hbWUiOiJzIiwiZmFtaWx5X25hbWUiOiJwIiwibmFtZSI6InNwIiwiYW1yIjpbInB3ZCIsInJzYSJdLCJ1bmlxdWVfbmFtZSI6InNwQGNpdHJpeHAuY29tIiwiYXBwaWQiOiIyOWQ5ZWQ5OC1hNDY5LTQ1MzYtYWRlMi1mOTgxYmMxZDYwNWUiLCJhcHBpZGFjciI6IjAiLCJzY3AiOiJtZG1fZGVsZWdhdGlvbiIsImFjciI6IjEiLCJpcGFkZHIiOiI2My4xMTAuNTEuMTEiLCJkZXZpY2VpZCI6ImQyNzU3NzY0LWFiOTEtNDBiMS05MmM2LTViOWE4MWYxODNiYyJ9";
public static void main(String[] args) throws UnsupportedEncodingException {
// TODO Auto-generated method stub
String certString = "-----BEGIN CERTIFICATE-----\r\n" + certificate + "\r\n-----END CERTIFICATE-----";
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
CertificateFactory cf;
try {
cf = CertificateFactory.getInstance("X.509");
InputStream stream = new ByteArrayInputStream(certString.getBytes()); //StandardCharsets.UTF_8
java.security.cert.Certificate cert = cf.generateCertificate(stream);
PublicKey pk = cert.getPublicKey();
//verifying content with signature and content :
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initVerify( pk );
sig.update(data.getBytes());
Boolean ret = sig.verify(signedData.getBytes());
} catch (CertificateException | SignatureException | NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
}
The signature part of a JWT is base64url encoded (see JWS §7.1) so you'll need to properly decode it before verification.
Replace the line Boolean ret = sig.verify(signedData.getBytes()); with something like the following (using the Base64 decoder from Apache Commons Codec),
byte[] signature = org.apache.commons.codec.binary.Base64.decodeBase64(signedData);
Boolean ret = sig.verify(signature);
And the signature on that JWT should verify for you.
Having said that, I'd very much recommend using a library for JWT processing. A decent library will handle stuff like that for you and can provide more JWT functionality too.
For example, the following using the jose4j JWT library could replace the stuff from the code in the question after getting the public key from the certificate. This not only verifies the signature per the spec but also validates the claims in the JWT to make sure it's still valid, was issued to you, etc..
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setVerificationKey(pk)
.setRequireExpirationTime()
.setExpectedAudience("https://citrixp.com:8443/")
.setExpectedIssuer("https://sts.windows.net/dd9b6a3e-29d1-4254-a746-e02941444517/")
.build();
JwtClaims claims = jwtConsumer.processToClaims(data + "." + signedData);
System.out.println("Subject: " + claims.getSubject());
System.out.println("UPN: " + claims.getStringClaimValue("upn")); // or whatever, etc....
That JWT expired a few days so the processToClaims will throw an exception, which is what you want. You can add a .setEvaluationTime(NumericDate.fromSeconds(1442626055)) when building the JwtConsumer to get it to work for the given JWT though.
I write the following code for signing the message and then verify it, in java by Bouncy Castle.
signing work properly but verifying not work. the result of code print:
signature tampered
can not recover
and return null.
why eng.hasFullMessage() function return false and why the following code doesn't work?thanks all.
public static String sigVer(PublicKey pu, PrivateKey pr, String original) throws Exception{
//sign
BigInteger big = ((RSAKey) pu).getModulus();
byte[] text = original.getBytes();
RSAKeyParameters rsaPriv = new RSAKeyParameters(true, big,((RSAPrivateKey) pr).getPrivateExponent());
RSAKeyParameters rsaPublic = new RSAKeyParameters(false, big,((RSAPublicKey) pu).getPublicExponent());
RSAEngine rsa = new RSAEngine();
byte[] data;
Digest dig = new SHA1Digest();
ISO9796d2Signer eng = new ISO9796d2Signer(rsa, dig, true);
eng.init(true, rsaPriv);
eng.update(text[0]);
eng.update(text, 1, text.length - 1);
data = eng.generateSignature();
String signature = data.toString();
//verify
eng = new ISO9796d2Signer(rsa, dig, true);
eng.init(false, rsaPublic);
text = signature.getBytes();
if (!eng.verifySignature(text)) {
System.out.println("signature tampered");
}
try{
if (eng.hasFullMessage()) {
eng.updateWithRecoveredMessage(signature.getBytes());
}
byte[] message = eng.getRecoveredMessage();
String ss = message.toString();
return ss;
}
catch (Exception e) {
System.out.println("can not recover");
return null;
}
}
Actually to verify large messages you have to provide the input for verification which is the original message and not only the signature which works only for full recovery
//verify
eng = new ISO9796d2Signer(rsa, dig, true);
eng.init(false, rsaPublic);
// when verifying there has to be also the original plain text
eng.update(text,0,text.length);
signBytes = signature.getBytes();
if (!eng.verifySignature(signBytes)) {
System.out.println("signature tampered");
}
I played around with this method and also receive the errors. In addition the "update" method mentioned does not work and the "updateWithRecoveredMessage" does not exist.
After some testing I figured that:
I have to sue getBytes("UTF-8") and String s = new String(message, "UTF-8")
I can use up to 234 bytes in the signature, with 235 it will break. (guess it would be 256 bytes but some are used for padding/markers)
If I understand correctly the problem is that the signer only allows a certain amount of bytes to be included in the signature.
If you use a longer payload you MUST include the payload in the verification step as well:
eng.init(false, rsaPublic);
byte[] message = payload.getBytes("UTF-8");
eng.update(message, 0, message.length);
then verification works just fine and you get the first part of the payload with eng.getRecoveredMessage().
For me this defeated the purpose, so I went another way.
The workaround I use is to two a two-step approach:
1) I generate a short key which is stored in the signature
2) use a symmetric (i.e. AES) to encrypt the large payload. I also generate a hash for the payload.
3) the key and hash for the payload is the one included in the signature.
Most of the times we don't have the original message to update and verifiy by the signature. On the other hand the length is limited to 234 bytes.
OK, this is another of those "I have no real idea where to start" questions, so hopefully the answer is simple. However, I don't really know what to search for, and my attempts so far haven't turned up much of use.
I want to read a private key from a (currently on-disk) file. Ultimately the key will reside in a database, but this will be good enough for the moment and that difference should have no real bearing on parsing the key material. I have been able to create a Credential instance that holds the public part of the key (confirmed by debugger), but I can't seem to figure out how to read the private part. The key pair was generated as:
openssl genrsa 512 > d:\host.key
openssl req -new -x509 -nodes -sha1 -days 365 -key d:\host.key > d:\host.cert
(Yes, I know that 512 bit RSA keys were broken long ago. However, for trying to get the API to work, I see no reason to exhaust the system entropy supply needlessly.)
The code thus far is:
import org.opensaml.xml.security.credential.Credential;
import org.opensaml.xml.security.x509.BasicX509Credential;
private Credential getSigningCredential()
throws java.security.cert.CertificateException, IOException {
BasicX509Credential credential = new BasicX509Credential();
credential.setUsageType(UsageType.SIGNING);
// read public key
InputStream inStream = new FileInputStream("d:\\host.cert");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)cf.generateCertificate(inStream);
inStream.close();
credential.setEntityCertificate(cert);
// TODO: read private key
// done.
return credential;
}
But how do I read the file host.key into the private key portion of credential, so I can use the generated Credential instance to sign data?
BasicX509Credential is not part from standard Java; I suppose you are talking about org.opensaml.xml.security.x509.BasicX509Credential from OpenSAML.
You want a PrivateKey which you will set with credential.setPrivateKey(). To get a PrivateKey, you must first convert the private key into a format that Java can read, namely PKCS#8:
openssl pkcs8 -topk8 -nocrypt -outform DER < D:\host.key > D:\host.pk8
Then, from Java:
RandomAccessFile raf = new RandomAccessFile("d:\\host.pk8", "r");
byte[] buf = new byte[(int)raf.length()];
raf.readFully(buf);
raf.close();
PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(buf);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privKey = kf.generatePrivate(kspec);
and voilà! you have your PrivateKey.
By default, openssl writes key in its own format (for RSA keys, PKCS#8 happens to be a wrapper around that format), and it encodes them in PEM, which Base64 with a header and a footer. Both characteristics are unsupported by plain Java, hence the conversion to PKCS#8. The -nocrypt option is because PKCS#8 supports optional password-based encryption of private key.
Warning: you really really want to use a longer RSA key. 512 bits are weak; a 512-bit RSA key was broken in 1999 with a few hundred computers. In 2011, with 12 years of technological advances, one should assume that a 512-bit RSA key can be broken by almost anybody. Therefore, use 1024-bit RSA keys at least (preferably, 2048-bit; the computational overhead when using the key is not that bad, you will still be able to perform hundred of signatures per second).
This question is related to SAML and is also relevant for someone who wants to retrieve a private key for signing an XMLObject. The answer above works great and it also possible to retrieve a private key from a keystore as well:
Properties sigProperties = new Properties();
sigProperties.put("org.apache.ws.security.crypto.provider","org.apache.ws.security.components.crypto.Merlin");
sigProperties.put("org.apache.ws.security.crypto.merlin.keystore.type","jks");
sigProperties.put("org.apache.ws.security.crypto.merlin.keystore.password","keypass");
sigProperties.put("org.apache.ws.security.crypto.merlin.keystore.alias","keyalias");
sigProperties.put("org.apache.ws.security.crypto.merlin.keystore.file","keystore.jks");
Crypto issuerCrypto = CryptoFactory.getInstance(sigProperties);
String issuerKeyName = (String) sigProperties.get("org.apache.ws.security.crypto.merlin.keystore.alias");
//See http://ws.apache.org/wss4j/xref/org/apache/ws/security/saml/ext/AssertionWrapper.html 'signAssertion' method
// prepare to sign the SAML token
CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
cryptoType.setAlias(issuerKeyName);
X509Certificate[] issuerCerts = issuerCrypto.getX509Certificates(cryptoType);
if (issuerCerts == null) {
throw new WSSecurityException(
"No issuer certs were found to sign the SAML Assertion using issuer name: "
+ issuerKeyName);
}
String password = ADSUnitTestUtils.getPrivateKeyPasswordFromAlias(issuerKeyName);
PrivateKey privateKey = null;
try {
privateKey = issuerCrypto.getPrivateKey(issuerKeyName, password);
} catch (Exception ex) {
throw new WSSecurityException(ex.getMessage(), ex);
}
BasicX509Credential signingCredential = new BasicX509Credential();
signingCredential.setEntityCertificate(issuerCerts[0]);
signingCredential.setPrivateKey(privateKey);
signature.setSigningCredential(signingCredential);
This is more code than the original query requested, but it looks they are trying to get at a BasicX509Credential.
Thanks,
Yogesh