import pfx (public/private keypair) into keystore
I have an existing certificate (public/private keypair) that I'm using in Microsoft IIS. Using Cert Manager in Windows2000 I export the certificate preserving the private key into a pfx file. I need to import the public/private keypair into the keystore. I also have the original certificate request and reply from Verisign if that helps any. I've looked everywhere and have been unable to find any information about doing this. Please Help!
If there is a way to do this using keytool that would be great. If someone knows how to programmatically do this that would also be great.
Thanks in advance,
Trey Caldwell
Software Engineer
Intrannuity, LLC
trey746@intrannuity.com
[724 byte] By [
trey] at [2007-9-26 17:15:56]

I finally got it!I found someone's program they used to do what I needed, after modifying many parts of the program it worked.
trey at 2007-7-2 22:04:17 >

Can you send me the sample code. I am getting an error as unknown attr1.3.6.1.4.1.311.17.1Thankx
pragy at 2007-7-2 22:04:17 >

Can you send me the sample code. I am getting an error as unknown attr1.3.6.1.4.1.311.17.1Thankx
pragy at 2007-7-2 22:04:17 >

Export cert from Netscape instead of IE.
In advance, i am sorry about any inconvenience.I am having trouble with importing pfx(private key and cert) into keystore.Could you please help me out?Thanks ^^
cjay at 2007-7-2 22:04:17 >

The Sun's PKCS12 Keystore seems not to work properlu with the .pfx format as exported from IE and other windows programs.
You can use other JCA/JCE providers that works. I am using Bouncy Castle (http://www.bouncycastle.org) that fits the bill perfectly.
Some code to check if your .pfx keystore file is working (I am writing from memory). If you exported the complete certChain, you will have three aliases:
* First one, the subject certificate
* Second one, the privatekey (named after Windoze Object SID)
* Third one, the CA (or issuer) certificate
Cert retrieval (e.g. keyStore.getCertificateChain()) works for the first alias as expected, while keyStore.getPrivateKey() works with the second alias found in the .PFX.
This is an issue that Sun may or may not fix in future releases of the JSSE PKCS12 KeyStore implementation. Until then, use BC !
// Sun's PKCS12 KeyStore does not work for IE-exported PKCS12
import java.security.KeyStore;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.*;
...
FileInputStream fis = new FileInputStream("mykeys.pfx");
// Instantiate BouncyCastle KeyStore implementation
KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC");
keyStore.load(fis, password);
fis.close();
Enumeration aliases = keyStore.getAliases();
while(aliases.hasNextElement()) {
System.out.println(aliases.nextElement());
}
I fixed some code error in compiling.
import java.io.*;
import java.util.*;
import java.security.KeyStore;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.*;
public class EsignWithBC {
public static final String KEY_STORE_PASSWORD = "PASSWORD";
public static void main(String[] args){
char[] passwd = KEY_STORE_PASSWORD.toCharArray();
KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC");
try{
FileInputStream fis = new FileInputStream("D:\\jCode\\src\\cert4office.pfx");
keyStore.load(fis, passwd);
fis.close();
}catch(Exception e){
e.printStackTrace();
}
Enumeration aliases = keyStore.aliases();
while(aliases.hasNextElements()) {
System.out.println(aliases.nextElement());
}
}
}
My code has a error. Somebody want to use that must fix (30 line)hasNextElements->hasMoreElements
But this code has a Running Exception.
java.security.NoSuchProviderException: no such provider: BC
at java.security.Security.getEngineClassName(Security.java:600)
at java.security.Security.getImpl(Security.java:1043)
at java.security.KeyStore.getInstance(KeyStore.java:199)
at EsignWithBC.main(EsignWithBC.java:21)
Is there anybody can explain about this?
This is successful code to import PKCS12 file
import java.io.*;
import java.util.*;
import java.security.KeyStore;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
//import org.bouncycastle.jce.provider.BouncyCastleProvider;
//import org.bouncycastle.jce.*;
public class EsignWithBC {
public static final String KEY_STORE_PASSWORD = "kkkk";
public static void main(String[] args){
char[] passwd = KEY_STORE_PASSWORD.toCharArray();
try{
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream fis = new FileInputStream("D:\\jCode\\src\\aaa.pfx");
keyStore.load(fis, passwd);
fis.close();
Enumeration aliases = keyStore.aliases();
while(aliases.hasMoreElements()) {
System.out.println(aliases.nextElement());
}
}catch(Exception e){
e.printStackTrace();
}
}
}
You must add the following lines to your code (there are also other ways): java.security.Provider provider = org.bouncycastle.jce.provider.BouncyCastleProvider;java.security.Security.addProvider(provider); Good luck, Nuno Guerreiro
Sorry, I meant:java.security.Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider();java.security.Security.addProvider(provider);
I am trying to do mutual certificate authentication (client/server authentication), and getting following error.
Anybody has any clue?
SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown
My code is below.
-
import com.sun.net.ssl.HttpsURLConnection;
import java.security.cert.*;
import javax.net.ssl.*;
import java.security.*;
import java.net.URL;
import java.io.*;
import java.util.Enumeration;
public class ClientCert {
private static SSLSocketFactory getSocketFactory() {
SSLSocketFactory theFactory = null;
try {
// set up key manager to do server authentication
SSLContext theContext;
KeyManagerFactory theKeyManagerFactory;
KeyStore theKeyStore;
char[] thePassword = "goldy123".toCharArray();
theContext = SSLContext.getInstance("TLS");
theKeyManagerFactory = KeyManagerFactory.getInstance("SunX509");
theKeyStore = KeyStore.getInstance("JKS");
theKeyStore.load(new FileInputStream("c:/castore"), thePassword);
//java.security.cert.Certificate certi[] = theKeyStore.getCertificateChain("ca");
// System.out.println("Certificate "+certi.length);
theKeyManagerFactory.init(theKeyStore, thePassword);
KeyManager managers[] = theKeyManagerFactory.getKeyManagers();
theContext.init(managers, null, null);
theFactory = theContext.getSocketFactory();
return theFactory;
} catch (Exception e) {
System.err.println("Failed to create a server socket factory...");
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
try {
System.setProperty("java.protocol.handler.pkgs","com.sun.net.ssl.internal.www.protocol");
java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
com.sun.net.ssl.HostnameVerifier hv=new com.sun.net.ssl.HostnameVerifier() {
public boolean verify(String urlHostname, String certHostname) {
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hv);
URL mioUrl = new URL("https://viveksharma:9090/LoginPage.do?userName=root&password=password");
//URL mioUrl = new URL("https://www.verisign.com");
//SSLSocketFactory factory = getFactorySSLFromCert(mioCertFile ,mioCertPswd );
//HttpsURLConnection.setDefaultSSLSocketFactory(factory);
//System.setProperty("javax.net.ssl.keyStore","C:/castore");
//System.setProperty("javax.net.ssl.keyStorePassword","goldy123");
System.setProperty("javax.net.ssl.trustStore","C:/vivekstore");
System.setProperty("javax.net.ssl.trustStorePassword","goldy123");
HttpsURLConnection.setDefaultSSLSocketFactory(getSocketFactory());
HttpsURLConnection urlConn = (HttpsURLConnection)mioUrl.openConnection();
urlConn.connect();
//urlConn.setDoInput(true);
// urlConn.setUseCaches(false);
javax.security.cert.X509Certificate ch[] = urlConn.getServerCertificateChain();
System.out.println(ch[0]);
InputStreamReader streamIn = new InputStreamReader(urlConn.getInputStream());
BufferedReader in = new BufferedReader(streamIn);
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Could we retrive the password from the keystore as when i trying to import .cer file into carets, it is asking for the password. I do not know what is the password. I uninstalled j2se 1.5 version and installed it again but still it is asking for the password which I do not know. I tried giving the default password 'changeit', it is giving java.IO.Exception. Any idea on this
Hi,
Did anybody figure out the problem of pfx importing into the keystore.
I have my pfx file and it shows just one alias.
I am pretty sure it works fine because the p12 file from which it is imported is successfully installed in IE and am able to access the secured site with successful client authentication.
Does anyone have any clue about it.
Regards,
Kushal.
Im having the same problem. My only alias shown is something like this:
4f6319a7365d3dfe7e10210a9e1e9741_3c0b8c1d-2cbf-4041-a89a-08bb0da38dea
I have been using BouncyCastle. My certificate works fine, and have tried with it in .P12 and .PFX format.
Could anyone please help us?.
Thanks a lot for your help!
Alfredito,
I finally solved the problem.
Step 1.
I have a pkcs12(.pfx or .p12) file exported from IE, but it has some attributes cannot be identified by jdk. So I import the pkcs12 file to NetScape and export form NetScape to convert the pkcs12 file . Then I use some code to convert the pkcs12 file to jdk keystore file(.jks).
Here is the code convert .pfx file to .jks.(foreward from someone's program)
import java.security.KeyStore;
import java.security.Key;
import java.security.cert.Certificate;
import java.io.*;
import java.util.*;
public class ConvertPKCS12ToJKS{
public static final String PKCS12 = "PKCS12";
public static final String JKS = "JKS";
public static final String INPUT_KEYSTORE_FILE= "file.p12";
public static final String KEYSTORE_PASSWORD = "111111";
public static final String OUTPUT_KEYSTORE_FILE= "file.jks";
public static void main(String[] args){
try{
KeyStore inputKeyStore = KeyStore.getInstance("PKCS12");
FileInputStream fis = new FileInputStream(INPUT_KEYSTORE_FILE);
char[] nPassword = null;
if ((KEYSTORE_PASSWORD == null) || KEYSTORE_PASSWORD.trim().equals("")){
nPassword = null;
}
else{
nPassword = KEYSTORE_PASSWORD.toCharArray();
}
inputKeyStore.load(fis, nPassword);
fis.close();
KeyStore outputKeyStore = KeyStore.getInstance("JKS");
outputKeyStore.load(null, "123456".toCharArray());
Enumeration enum = inputKeyStore.aliases();
while (enum.hasMoreElements()){ // we are readin just one certificate.
String keyAlias = (String)enum.nextElement();
System.out.println("alias=[" + keyAlias + "]");
if (inputKeyStore.isKeyEntry(keyAlias)){
Key key = inputKeyStore.getKey(keyAlias, nPassword);
Certificate[] certChain = inputKeyStore.getCertificateChain(keyAlias);
outputKeyStore.setKeyEntry("outkey", key, "111111".toCharArray(), certChain);
}
}
FileOutputStream out = new FileOutputStream(OUTPUT_KEYSTORE_FILE);
outputKeyStore.store(out, nPassword);
out.close();
}
catch (Exception e){
e.printStackTrace();
}
}
}
Step 2
I add certificates provided by https server to the keystore(.jks). You can find some codes on Web.
Step 3
Use the following code to complete ssl httpclient(apache) with client authorization.
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.params.HttpMethodParams;
import java.io.*;
public class HttpClientTutorial {
private static String url = "https://www.test.com";
public static void main(String[] args) {
System.setProperty("javax.net.debug", "all");
System.setProperty("javax.net.ssl.trustStore", "file.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "111111");
System.setProperty("javax.net.ssl.keyStore", "file.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "111111");
HttpClient client = new HttpClient();
// Create a method instance.
GetMethod method = new GetMethod(url);
method.setRequestHeader("User-Agent", "MSIE");
// Provide custom retry handler is necessary
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(1, false));
try {
// Execute the method.
int statusCode = client.executeMethod(method);
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: " + method.getStatusLine());
}
// Read the response body.
byte[] responseBody = method.getResponseBody();
// Deal with the response.
// Use caution: ensure correct character encoding and is not binary data
System.out.println(new String(responseBody));
}
catch (HttpException e) {
System.err.println("Fatal protocol violation: " + e.getMessage());
e.printStackTrace();
}
catch (IOException e) {
System.err.println("Fatal transport error: " + e.getMessage());
e.printStackTrace();
}
finally {
// Release the connection.
method.releaseConnection();
}
}
}
good luck!
Here's a simple way of converting pfx to keystore. You'll need jars from bouncycastle.org and jsmime.sourceforge.net.
try{
Security.addProvider(new BouncyCastleProvider());
KeyStore ks = KeyStore.getInstance("PKCS12", "BC");
ks.load( new FileInputStream( "c:\\keystore.pfx" ), "".toCharArray() );
PrivateKey pk = PFXUtils.getPrivateKey( ks );
Certificate[] certs = PFXUtils.getAllX509Certificate(ks);
KeyStore newKs = KeyStore.getInstance("JKS");
newKs.load(null, null);
newKs.setKeyEntry("MyAlias", pk, "password".toCharArray(), certs);
newKs.store( new FileOutputStream("c:\\keystore.keystore"), "password".toCharArray());
}
catch( Exception e ){
e.printStackTrace();
}
I am trying to perform mutual authentication between my java app and a website. I have attempted to follow the instructions described in this forum but nothing has worked for me. If any one could offer some assistance it would be greatly appreciated. I have been supplied a .pfx file from the site and I created a .jks store as described above and now i'm trying to connect to the site. I am working with code nearly identical to that shown above involving apache.commons.HttpClient. When i run this code it seems as though certificate exchange is happening correctly but I keep getting the following error:
Fatal transport error: The server auth.pathnet.ca failed to respond
org.apache.commons.httpclient.NoHttpResponseException: The server auth.pathnet.ca failed to respond
at org.apache.commons.httpclient.HttpMethodBase.readStatusLine(HttpMethodBase.java:1835)
at org.apache.commons.httpclient.HttpMethodBase.readResponse(HttpMethodBase.java:1590)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:995)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:395)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:170)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:396)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:324)
at netmedical.nmr.lab.HttpClientTutorial.main(HttpClientTutorial.java:36)
It seems as though the site isn't sending me any data but what confuses me is that if I use the certificate with my browser I receive an html response. Maybe somebody has some idea of what could be the problem, or even the name of a testsite for mutual authentication would be appreciated. Thanks.
hii have the same prob i have to read the priavte/public keys from the .pfx file in j2me im using bouncy castle light weight API can any body help me
You don't have to import the certificate in the Java keystore. An easy way to configure client-authentication with a .pfx certifacte is to set some system properties:
System.setProperty("javax.net.ssl.keyStore", <path-to-pfx-file>);
System.setProperty("javax.net.ssl.keyStorePassword", <certificate-password>);
System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
Now if you connect to a SSL-server that requires client-authentication, the configured certificate will be used.
openssl pkcs12 -in m1.pfx -nodes -nocerts -out m1.key
I'm having a problem opening pfx files with the java 1.5 implementation. When i try to get the private key from my certificate without any password i get an exception.
Do you guys already had this problem? If yes, how do you solve it?
(Without putting a password on the certificate)
This worked for me! Thanks a million.
How did I get it working:
1) Export the certificate, including the personal key from IE. Choose any password.
2) Add these three magic lines to your client (replace certificate password with the password you chose at step 1:
System.setProperty("javax.net.ssl.keyStore", <path-to-pfx-file>);
System.setProperty("javax.net.ssl.keyStorePassword", <certificate-password>);
System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
3) And it works! My client calls a webservice over ssl and indeed hands over the certificate in the p12 keystore!!!
Kudos for gjkreeft . A bit late, I know.
http://www.alphaworks.ibm.com/tech/keyman/download -- great IBM tools. Can create new keystore and import pkcs12 here.