I'm trying to accept my SSL certificate for API tests. For that, I exported my certificate with IE (with the second option : x.509 binary encod base 64 (*.cer) I added it in the keystore with this command line :
keytool -importcert -file certificate.cer -keystore "C:\Program
Files\Java\jdk1.8.0_111\jre\lib\security\cacerts" -alias "certificatealias"
To list keystore and check if I have my certificate entry, I use this command line :
keytool -list -v -keystore "C:\Program
Files\Java\jdk1.8.0_111\jre\lib\security\cacerts" > java_cacerts.txt
I have my certificate entry inside :
Nom d'alias : certificatealias Date de création : 6 déc. 2016 Type d'entrée : trustedCertEntry
Propriétaire : CN=Test, O=Test Emetteur : CN=Test, O=Test Numéro de série : XXXX Valide du : xxx au : xxxx
Empreintes du certificat : MD5: Xxxxxx SHA1 :xxxx SHA256 : XXXX
Nom de l'algorithme de signature : SHA256withRSA Version : 3
In my code, I have :
FileInputStream in = new FileInputStream("certificate.jks");
BufferedInputStream bis = new BufferedInputStream(in);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(bis, "changeit".toCharArray());
Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
System.out.println("alias: " + alias);
System.out.println("bis.available: " +bis.available());
System.out.println("bis: "+ bis.toString());
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate x509 = (X509Certificate) cf.generateCertificate(bis);
KeyStore.Entry newEntry = new KeyStore.TrustedCertificateEntry(x509);
ks.setEntry("certificatealias", newEntry, null);
}
I received an error :
java.security.cert.CertificateException: Could not parse certificate: java.io.IOException: Empty input
In my console I have :
alias: certificatealias
bis.available: 0
bis: java.io.BufferedInputStream@8xx9d4
The error is on cf.generateCertificate(bis).
Why I have this error? cf and bis are not null or empty...
I saw it can be the keystore type that can be wrong (see the post 3 years ago). KeyStore.getDefaultType() return JKS. That should be good, isn't ?
I've checked with the command line :
keytool -list -keystore <keystore_location> I've the type :
Type de fichier de clés : JKS
Fournisseur de fichier de clés : SUN
Any hint will be very helpful!
bisinput stream. You can't use that create a certificate out of it, because it is the whole keystore. If you need to get the certificate object and add it to your keystore, you should load the certificate using input stream (like you did for the keystore), and feed that input stream to thegenerateCertificatemethod. You could use input stream likeFileInputStreamto load the certificate.FileInputStream certificate = new FileInputStream("certificate.cer"); BufferedInputStream bis2 = new BufferedInputStream(certificate);and corrected the line to cf.generateCertificate(bis2);` However, I get another errorjavax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested targetcf.generateCertificate(bis2)I have : `cert: [ [ Version: V3 Subject: CN=Test, O=Test Signature Algorithm: SHA256withRSA, OID = XX Key: Sun RSA public key, 1024 bits modulus: XX (too long) public exponent: xx Validity: [From: X To: X Issuer: CN=Test, O=Test SerialNumber: [ xx] ] Algorithm: [SHA256withRSA] Signature: XX (too long) ] '