Communication with server that support ssl in java - java

I have a question for sslConnectionin java , I write below code for client side ( this application have to connect to server, I have server that support ssl )but I get this error” javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target”
How can I resolve my problem ?
public static void main(String[] args) {
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
PrintStream out = System.out;
SSLSocketFactory f =
(SSLSocketFactory) SSLSocketFactory.getDefault();
try {
SSLSocket c =
(SSLSocket) f.createSocket("192.168.10.38", 7701);
printSocketInfo(c);
System.out.println("End printSocketInfo");
c.startHandshake();
System.out.println("HandShake oK");
BufferedWriter w = new BufferedWriter(
new OutputStreamWriter(c.getOutputStream()));
BufferedReader r = new BufferedReader(
new InputStreamReader(c.getInputStream()));
String m = null;
// String m=
while ((m=r.readLine())!= null) {
System.out.println("11111");
out.println(m);
m = in.readLine();
System.out.println("M is: "+ m);
w.write(m,0,m.length());
w.newLine();
w.flush();
}
w.close();
r.close();
c.close();
} catch (IOException e) {
System.err.println(e.toString());
}
}
private static void printSocketInfo(SSLSocket s) {
System.out.println("Socket class: "+s.getClass());
System.out.println(" Remote address = "
+s.getInetAddress().toString());
System.out.println(" Remote port = "+s.getPort());
System.out.println(" Local socket address = "
+s.getLocalSocketAddress().toString());
System.out.println(" Local address = "
+s.getLocalAddress().toString());
System.out.println(" Local port = "+s.getLocalPort());
System.out.println(" Need client authentication = "
+s.getNeedClientAuth());
SSLSession ss = s.getSession();
System.out.println(" Cipher suite = "+ss.getCipherSuite());
System.out.println(" Protocol = "+ss.getProtocol());
}
I have a certificate file, how have to use this certificate?
Best Regards

Is it Self Signed certificate
If yes then you have two options
First Option :
Import Certificate authority certificate in Global Java Certificate Trust store. This store is located at
%Java Installation%/jre/lib/security/cacerts
To import it you can use Keytool command which comes with java installation
keytool -import -alias keyName -file yourcertificate.crt -keystore cacerts
Advantage:
No code modification needed.
Simple to deploy
Disadvantage:
cacert file will be overwritten in next java update. You have to
import certificate again.
Requires administrative privileges (both on Linux and windows)
Second Option :
If you want to bypass certificate validation follow Java: Overriding function to disable SSL certificate check
Else
create new Trust store for your program
keytool -import -alias keyName -file yourcertificate.crt -keystore yourtruststore
This command will ask for password two times. Enter any password you want and input "yes" for any questions
A file will be created at current directory by name "yourtruststore"
Now you need to use this trust store in your program
SSLSocketFactory sslFactory = null;
InputStream trustStore = null;
KeyStore keyStore = null;
trustStore = new FileInputStream("<your trust store absolute path>");
keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(trustStore, "<your trust store password>".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
sslFactory = ctx.getSocketFactory();
You can use this socket factory to open new sockets

You have to put the HTTPS certificate to your JVM. To get the certificate from the HTTPS, go through a browser, then click on the "lock" logo on the address bar. You should be able to export the certificate.
Solution for Linux: In $JAVA_HOME/jre/lib/security, use this command:
sudo keytool -import -alias keyName -file /[pathForYourKey]/keyName.cert -keystore cacerts
Default password for "cacerts" is changeit.

Related

SSLHandshakeException - handshake failed on Android 6.0

I am working on an android application which need to download through HTTPS connection. But I got SSLHandshakeException - handshake failed.
What I have done is as below
First,using openssl to get server certificate chain
openssl s_client -connect www.coles.com.au:443
And got
Certificate chain
0 s:/C=AU/ST=Victoria/L=Hawthorn East/O=Coles Supermarkets Australia Pty Ltd/OU=Web Team/CN=coles.com.au
i:/C=US/O=thawte, Inc./CN=thawte SSL CA - G2
1 s:/C=US/O=thawte, Inc./CN=thawte SSL CA - G2
i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIE3zCCA8egAwIBAgIQfc9y5DSMNxERU663wd4m+DANBgkqhkiG9w0BAQsFADBB
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMuMRswGQYDVQQDExJ0
aGF3dGUgU1NMIENBIC0gRzIwHhcNMTUxMDMwMDAwMDAwWhcNMTgxMDI5MjM1OTU5
WjCBkTELMAkGA1UEBhMCQVUxETAPBgNVBAgMCFZpY3RvcmlhMRYwFAYDVQQHDA1I
YXd0aG9ybiBFYXN0MS0wKwYDVQQKDCRDb2xlcyBTdXBlcm1hcmtldHMgQXVzdHJh
bGlhIFB0eSBMdGQxETAPBgNVBAsMCFdlYiBUZWFtMRUwEwYDVQQDDAxjb2xlcy5j
b20uYXUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBoLhSH1Q/3YGQ
d0d5FEza3EaW4bWYDfHtg0oReJ8OvONWYpPgKZ0HZPUi6m6CDhWKXRmxZbiRDGQR
ihRYpAcRnw/DbkN6+eDSHU0I5eZD4YpdbhvAzeVOkiSyQXipvAJZFvomHsjCIvIu
g/2EInwAeTkgDSJY+PUbiiy+Ooko/H2XpjV0+C3eb2RY/pNV+Df5FG1bzVtEWNna
ncqYK9tJlyfDNM9TENzZdxmLtJsFYzlniJcxVgjPw4uSI4N3Cnr3n3PuSKSQuavl
D7k4H7wuwPvOn6l1wAj7fbgq16ZfF9vUvLXsn/yc99V1/7oYIVA4KDxgLhU10IVp
k2JPDZN9AgMBAAGjggGAMIIBfDApBgNVHREEIjAgghB3d3cuY29sZXMuY29tLmF1
ggxjb2xlcy5jb20uYXUwCQYDVR0TBAIwADBuBgNVHSAEZzBlMGMGBmeBDAECAjBZ
MCYGCCsGAQUFBwIBFhpodHRwczovL3d3dy50aGF3dGUuY29tL2NwczAvBggrBgEF
BQcCAjAjDCFodHRwczovL3d3dy50aGF3dGUuY29tL3JlcG9zaXRvcnkwDgYDVR0P
AQH/BAQDAgWgMB8GA1UdIwQYMBaAFMJPSFf80U+awF04fQ4F29kutVJgMCsGA1Ud
HwQkMCIwIKAeoByGGmh0dHA6Ly90ai5zeW1jYi5jb20vdGouY3JsMB0GA1UdJQQW
MBQGCCsGAQUFBwMBBggrBgEFBQcDAjBXBggrBgEFBQcBAQRLMEkwHwYIKwYBBQUH
MAGGE2h0dHA6Ly90ai5zeW1jZC5jb20wJgYIKwYBBQUHMAKGGmh0dHA6Ly90ai5z
eW1jYi5jb20vdGouY3J0MA0GCSqGSIb3DQEBCwUAA4IBAQAkm5BJW0u7ZJFGVWip
xo/poAFHNMImBfofz8WJGN/npJwLKV0mV8FX6dRPEAjPWWT+I/JonwX7VVxAgUWj
3bl+XdIU3hj8cRh3yDnEvhKVKs3orr/jQnxSNx4JZCwmPUIuKK58R1dYCRV/hT7l
YYDMXj+RrAjhrgu7IgZJDCV9kcznBqMdbHLOb/P4PX6j8CsCufS6iGjKhBHTL/49
uuL9ACqH6BgGVctm4kELGcyS6e+VJ9rHI3P+1muOk4wKEVjps9rbPOmpUTk8WhXb
RghAwHrtQZEZMIAVMg2ksCkl/NGRl64Q1W/lW2JHun6ApdXPsGzTvzp3+Kmhrf5p
mLNK
-----END CERTIFICATE-----
subject=/C=AU/ST=Victoria/L=Hawthorn East/O=Coles Supermarkets Australia Pty Ltd/OU=Web Team/CN=coles.com.au
issuer=/C=US/O=thawte, Inc./CN=thawte SSL CA - G2
---
No client certificate CA names sent
Peer signing digest: SHA1
Then go to thawte website(https://search.thawte.com/support/ssl-digital-certificates/index?page=content&id=SO26817&actp=RSS&viewlocale=en_US#links) to download CA certificate(tell me if I did wrong or from wrong place to download) which is thawte_SSL_CA_G2.cer
Third, I have below code to connect
String url = "https://www.coles.com.au";
String strContent = "";
HttpURLConnection connection;
AssetManager assetManager = context.getAssets();
InputStream caInput = null;
try{
CertificateFactory cf = CertificateFactory.getInstance("X.509");
caInput = assetManager.open("thawte_SSL_CA_G2.cer");
Certificate ca = cf.generateCertificate(caInput);
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
URL urlObj = new URL(url);
HttpsURLConnection urlConnection =
(HttpsURLConnection)urlObj.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
InputStream in = urlConnection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
while(null != (strContent= reader.readLine())){
System.out.println(strContent);
}
}
catch (IOException e){
String exception = e.getMessage();
System.out.println(exception);
}
I use wireshark to capture and observe below happened
-> Client Hello
<- Server Hello
<- Certificate
<- Server Key Exchange
-> Client Key Exchange, Change Cipher Spec, Hello Request, Hello Request
<- FIN
Please help me on why I got handshake failed.
You should add all the ICA (intermediate certificates) and CA.
You could do the following
openssl s_client -showcerts -connect www.coles.com.au:443
Add all the certificates you receive to your trust store. (Strictly speaking only ICA and CA are enough in trust store)

Connecting Putty to a SSLSocket

What I’m trying to do is write a small test program to listen on an SSLSocket and connect to it using PuTTY (in SSH), then try to print lines that I typed in PuTTY session on java side. Problem that I’m currently facing is with the handshake. Looks like the sslsocket.startHandshake() does not complete and it’s just waiting at that point (I’m getting a “javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake” exception msg when I kill PuTTY).
Following is the command I used to create my key store:
keytool -genkeypair -keyalg RSA -alias test -keystore ks1.jks -storepass password1 -validity 360 -keysize 1024
Code:
...
char[] keyPassword = "password1".toCharArray();
FileInputStream keyFile = new FileInputStream("ks1.jks");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(keyFile, keyPassword);
SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(7777);
SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();
sslsocket.startHandshake();
InputStream inputstream = sslsocket.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
String string = null;
while ((string = bufferedreader.readLine()) != null) {
System.out.println(">" + string);
...
}
...
PuTTY does not know SSL.
It supports SSH, what is a completelly different protocol.
PuTTY also supports raw connection, but as SSL is a binary protocol, it is nearly impossible to "type" SSL packets on the console.

applet with SunMSCapi not working in linux

We have created a new site for our web where we let the users to sign a pdf document using an applet we have designed. The issue is that this applet works fine only in Windows OS and we would like to extend it to linux OS.
When we run the applet in linux we get this error message:
[opensc-pkcs11] reader-pcsc.c:896:pcsc_detect_readers:
SCardListReaders failed: 0x8010002e [opensc-pkcs11]
reader-pcsc.c:1015:pcsc_detect_readers: returning with: No readers
found [opensc-pkcs11] reader-pcsc.c:896:pcsc_detect_readers:
SCardListReaders failed: 0x8010002e [opensc-pkcs11]
reader-pcsc.c:1015:pcsc_detect_readers: returning with: No readers
found java.security.NoSuchProviderException: no such provider:
SunMSCAPI at sun.security.jca.GetInstance.getService(Unknown Source)
at sun.security.jca.GetInstance.getInstance(Unknown Source)
I think the problem comes when we try to read the certificated stored in the Windows OS with this call in our code:
KeyStore keystore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
keystore.load(null, null);
return keystore;
This is te function we use to obtain the list of certificates.
public KeyStore obtenerCertificados() throws Exception {
String osNombre = System.getProperty("os.name");
String osArquitectura = System.getProperty("os.arch");
String providerConfig = null;
String configuracionPKCS11 = null;
// LINUX
if(osNombre.contains(new StringBuffer("Linux")))
providerConfig = "name = OpenSC\nlibrary = /usr/lib/opensc-pkcs11.so\n";
// WINDOWS
else if(osNombre.contains(new StringBuffer("Windows")))
if(!osArquitectura.toLowerCase().contains("x86")){
System.out.println("Estamos en toLowerCase().contains x86");
providerConfig = "name = NSS"+"\n"+
"nssLibraryDirectory = "+"C:/Archivos de programa/Mozilla Firefox"+"\n"+
"nssSecmodDirectory = "+"C:/Users/SM/AppData/Local/Mozilla/Firefox/Profiles/plmk3eh9.default"+"\n"+
"nssDbMode = readOnly" + "\n" +
"nssModule = keystore" + "\n" +
"\r";
}
else{
System.out.println("Estamos en NO toLowerCase().contains x86");
providerConfig = "name = NSS"+"\n"+
"nssLibraryDirectory = "+"C:/Program Files (x86)/Mozilla Firefox"+"\n"+
"nssLibrary = "+"C:/Program Files (x86)/Mozilla Firefox/softokn3.dll"+"\n"+
"nssSecmodDirectory = "+"C:/Users/SM/AppData/Roaming/Mozilla/Firefox/Profiles/plmk3eh9.default"+"\n"+
"nssDbMode = readOnly" + "\n" +
"nssModule = keystore" + "\n" +
"\r";
}
// MAC OS
else {providerConfig = "name = OpenSC\nlibrary = /Library/OpenSC/lib/opensc-pkcs11.so\n";}
ByteArrayInputStream localByteArrayInputStream = new ByteArrayInputStream(providerConfig.getBytes());
SunPKCS11 _pk11provider = null;
try {
_pk11provider = new SunPKCS11(localByteArrayInputStream);
Security.addProvider(_pk11provider);
// _pk11provider.login(new Subject(), new DialogCallbackHandler());
}catch(Throwable e){
System.out.println(e.getMessage());
}
KeyStore keystore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
keystore.load(null, null);
return keystore;
}
Any ideas about how to extend this use to linux and MAC???
Thanks a lot for your help!!
You can not use SunMSCAPI provider in Linux or MAC OS X, this provider is Windows specific which deals with Windows keystore. If you want to use a Smart Card or Firefox keystore in Linux or MAC OS X through SunPKCS11 provider you must get an instance of java.security.KeyStore passing SunPKCS11 as provider, like you are doing with SunMSCAPI i.e:
ByteArrayInputStream confStream = ...// your configuration
SunPKCS11 pkcs11 = new SunPKCS11(confStream);
Security.addProvider(pkcs11);
KeyStore ks = KeyStore.getInstance("PKCS11", pkcs11);
ks.load(null, "your_pin".toCharArray());
With this code you load on the Keystore ks the keys from your configured PKCS11.
There is another way to do it if you want that your PKCS11 pin will be introduced by a third party later. To do so you can initialize your keystore with a java.security.KeyStore.CallbackHandlerProtection parameter like follows:
ByteArrayInputStream confStream = ...// your configuration
SunPKCS11 pkcs11 = new SunPKCS11(confStream);
Security.addProvider(pkcs11);
KeyStore.CallbackHandlerProtection cbhp = new KeyStore.CallbackHandlerProtection(new PinInputHandler(msg));
KeyStore.Builder builder = KeyStore.Builder.newInstance("PKCS11", pkcs11, cbhp);
builder.getKeyStore();
Note that PinInputHandler in this second sample must implements: javax.security.auth.callback.CallbackHandler.
Additionally in your code seems that you never loads the PKCS11 keys through SunPKCS11 provider (even in Windows case) because you are not instantiating a keystore with SunPKCS11 you are only adding it as a provider with Security.addProvider method and always you are instantiating only a keystore with SunMSCAPI, however probably in Windows you are getting some of your Smart cards keys because if you install Windows drivers for you smart card you can get their keys through Windows keystore.
Hope this helps,

Where to place SSL certificate for java application

Hello all
I want to generate a certificate using keystore than add this to my sevrer and browse my sever using IE. I need the steps for generating the certificate in plain english as all what i read in the internet is hard to be understod. The server socket is:
SSLServerSocketFactory ssf = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
SSLServerSocket Server = (SSLServerSocket)ssf.createServerSocket(1234);
String[] cipher = {"SSL_DH_anon_WITH_RC4_128_MD5"};
Server.setEnabledCipherSuites(cipher);
The certificate code is this but not sure where to pu it in my server:
InputStream infil = new FileInputStream("server.cer");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)cf.generateCertificate(infil);
infil.close();
KeyStore ks = null;
ks = KeyStore.getInstance("JKS", "SUN");
InputStream is = null;
is = new FileInputStream(new File("./keystore"));
ks.load(is,"rootroot".toCharArray());
See the Javadoc/Security/JSSE Reference.

How to connect to a secure website using SSL in Java with a pkcs12 file?

I have a pkcs12 file. I need to use this to connect to a webpage using https protocol. I came across some code where in order to connect to a secure web page i need to set the following system properties:
System.setProperty("javax.net.ssl.trustStore", "myTrustStore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
System.setProperty("javax.net.ssl.keyStore", "new_cert.p12");
System.setProperty("javax.net.ssl.keyStorePassword", "newpass");
I have the p12(pkcs12) file. All I need is a truststore file.
I extracted the certificates using:
openssl.exe pkcs12 -in c:/mykey.p12 -out c:/cert.txt -nokeys -clcerts
Now converted the cert PEM file to der
openssl.exe x509 -in c:/cert.txt -outform DER -out c:/CAcert.der
Now adding the der file to a keystore
keytool -import -file C:/Cacert.der -keystore mytruststore
Now I have the truststore, but when I use it, I get the following error
Exception in thread "main" java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)
Update:
After removing certain properties and setting only the "trustStore", "trustStorePassword" and "trustStoreType" property, I got the following exception
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
Please Help.
For anyone encountering a similar situation I was able to solve the issue above as follows:
Regenerate your pkcs12 file as follows:
openssl pkcs12 -in oldpkcs.p12 -out keys -passout pass:tmp
openssl pkcs12 -in keys -export -out new.p12 -passin pass:tmp -passout pass:newpasswd
Import the CA certificate from server into a TrustStore ( either your own, or the java keystore in $JAVA_HOME/jre/lib/security/cacerts, password: changeit).
Set the following system properties:
System.setProperty("javax.net.ssl.trustStore", "myTrustStore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
System.setProperty("javax.net.ssl.keyStore", "new.p12");
System.setProperty("javax.net.ssl.keyStorePassword", "newpasswd");
Test ur url.
Courtesy# http://forums.sun.com/thread.jspa?threadID=5296333
I cannot comment because of the 50pts threshhold, but I don't think that the answer provided in https://stackoverflow.com/a/537344/1341220 is correct.
What you are actually describing is how you insert server certificates into the systems default truststore:
$JAVA_HOME/jre/lib/security/cacerts, password: changeit)
This works, indeed, but it means that you did not really specify a trust store local to your project, but rather accepted the certificate universially in your system.
You actually never use your own truststore that you defined here:
System.setProperty("javax.net.ssl.trustStore", "myTrustStore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
It appears that you are extracting you certificate from the PKCS #12 key store and creating a new Java key store (with type "JKS"). You don't strictly have to provide a trust store password (although using one allows you to test the integrity of your root certificates).
So, try your program with only the following SSL properties set. The list shown in your question is over-specified and may be causing problems.
System.setProperty("javax.net.ssl.trustStore", "myTrustStore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
Also, using the PKCS #12 file directly as the trust store should work, as long as the CA certificate is detected as a "trusted" entry. But in that case, you'll have to specify the javax.net.ssl.trustStoreType property as "PKCS12" too.
Try with these properties only. If you get the same error, I suspect your problem is not the key store. If it still occurs, post more of the stack trace in your question to narrow the problem down.
The new error, "the trustAnchors parameter must be non-empty," could be due to setting the javax.net.ssl.trustStore property to a file that doesn't exist; if the file cannot be opened, an empty key store created, which would lead to this error.
This is an example to use ONLY p12 file it's not optimazed but it work.
The pkcs12 file where generated by OpenSSL by me.
Example how to load p12 file and build Trust zone from it...
It outputs certificates from p12 file and add good certs to TrustStore
KeyStore ks=KeyStore.getInstance("pkcs12");
ks.load(new FileInputStream("client_t_c1.p12"),"c1".toCharArray());
KeyStore jks=KeyStore.getInstance("JKS");
jks.load(null);
for (Enumeration<String>t=ks.aliases();t.hasMoreElements();)
{
String alias = t.nextElement();
System.out.println("#:" + alias);
if (ks.isKeyEntry(alias)){
Certificate[] a = ks.getCertificateChain(alias);
for (int i=0;i<a.length;i++)
{
X509Certificate x509 = (X509Certificate)a[i];
System.out.println(x509.getSubjectDN().toString());
if (i>0)
jks.setCertificateEntry(x509.getSubjectDN().toString(), x509);
System.out.println(ks.getCertificateAlias(x509));
System.out.println("ok");
}
}
}
System.out.println("init Stores...");
KeyManagerFactory kmf=KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "c1".toCharArray());
TrustManagerFactory tmf=TrustManagerFactory.getInstance("SunX509");
tmf.init(jks);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
URL url = new URL("https://test.domain:443");
String keyStore = "server.p12"
String keyStorePassword = "changeit";
String keyPassword = "changeit";
String KeyStoreType= "PKCS12";
String KeyManagerAlgorithm = "SunX509";
String SSLVersion = "SSLv3";
public HttpURLConnection getHttpsURLConnection(URL url, String keystore,
String keyStorePass,String keyPassword, String KeyStoreType
,String KeyManagerAlgorithm, String SSLVersion)
throws NoSuchAlgorithmException, KeyStoreException,
CertificateException, FileNotFoundException, IOException,
UnrecoverableKeyException, KeyManagementException {
System.setProperty("javax.net.debug","ssl,handshake,record");
SSLContext sslcontext = SSLContext.getInstance(SSLVersion);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerAlgorithm);
KeyStore ks = KeyStore.getInstance(KeyStoreType);
ks.load(new FileInputStream(keystore), keyStorePass.toCharArray());
kmf.init(ks, keyPassword.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
TrustManager[] tm = tmf.getTrustManagers();
sslcontext.init(kmf.getKeyManagers(), tm, null);
SSLSocketFactory sslSocketFactory = sslcontext.getSocketFactory();
HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
HttpsURLConnection httpsURLConnection = ( HttpsURLConnection)uRL.openConnection();
return httpsURLConnection;
}
This example shows how you can layer SSL on top of an existing socket, obtaining the client cert from a PKCS#12 file. It is appropriate when you need to connect to an upstream server via a proxy, and you want to handle the full protocol by yourself.
Essentially, however, once you have the SSL Context, you can apply it to an HttpsURLConnection, etc, etc.
KeyStore ks = KeyStore.getInstance("PKCS12");
InputStream is = ...;
char[] ksp = storePassword.toCharArray();
ks.load(is, ksp);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
char[] kp = keyPassword.toCharArray();
kmf.init(ks, kp);
sslContext = SSLContext.getInstance("SSLv3");
sslContext.init(kmf.getKeyManagers(), null, null);
SSLSocketFactory factory = sslContext.getSocketFactory();
SSLSocket sslsocket = (SSLSocket) factory.createSocket(socket, socket
.getInetAddress().getHostName(), socket.getPort(), true);
sslsocket.setUseClientMode(true);
sslsocket.setSoTimeout(soTimeout);
sslsocket.startHandshake();
The following steps will help you to sort your problem out.
Steps:
developer_identity.cer <= download from Apple
mykey.p12 <= Your private key
Commands to follow:
openssl x509 -in developer_identity.cer -inform DER -out developer_identity.pem -outform PEM
openssl pkcs12 -nocerts -in mykey.p12 -out mykey.pem
openssl pkcs12 -export -inkey mykey.pem -in developer_identity.pem -out iphone_dev.p12
Final p12 that we will require is iphone_dev.p12 file and the passphrase.
use this file as your p12 and then try. This indeed is the solution.:)
I realise that this article may be outdated but still I would like to ask smithsv to correct his source code, it contains many mistakes, I managed to correct most of them but still don't know what kind of object x509 could be.Here is the source code as I think is should be:
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.util.Enumeration;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
public class Connection2 {
public void connect() {
/*
* This is an example to use ONLY p12 file it's not optimazed but it
* work. The pkcs12 file where generated by OpenSSL by me. Example how
* to load p12 file and build Trust zone from it... It outputs
* certificates from p12 file and add good certs to TrustStore
*/
KeyStore ks = KeyStore.getInstance( "pkcs12" );
ks.load( new FileInputStream( cert.pfx ), "passwrd".toCharArray() );
KeyStore jks = KeyStore.getInstance( "JKS" );
jks.load( null );
for( Enumeration t = ks.aliases(); t.hasMoreElements(); ) {
String alias = (String )t.nextElement();
System.out.println( "#:" + alias );
if( ks.isKeyEntry( alias ) ) {
Certificate[] a = ks.getCertificateChain( alias );
for( int i = 0; i == 0; )
jks.setCertificateEntry( x509Cert.getSubjectDN().toString(), x509 );
System.out.println( ks.getCertificateAlias( x509 ) );
System.out.println( "ok" );
}
}
System.out.println( "init Stores..." );
KeyManagerFactory kmf = KeyManagerFactory.getInstance( "SunX509" );
kmf.init( ks, "c1".toCharArray() );
TrustManagerFactory tmf = TrustManagerFactory.getInstance( "SunX509" );
tmf.init( jks );
SSLContext ctx = SSLContext.getInstance( "TLS" );
ctx.init( kmf.getKeyManagers(), tmf.getTrustManagers(), null );
}
}

Categories