用pfx证书java双向认证_把CA证书生成的crt的证书和pem的私钥转换成java能够使用的keystore和pcks12的证书,实现https双向认证...
最近在做一個https雙向認證的工作,領導先讓我實現,我之前寫了一篇文章,把tomcat的生成證書和配置的實現寫了出來。
現在領導給了我服務器的CA證書的客戶端證書和私鑰,服務端信任證書,分別是crt和pem格式的文件,
試了很多方法,才把這個搞通,由于不同的平臺,證書格式和版本差異很大,包括文本證書和二進制證書文件。
通過openSSL 很容易把證書轉換出來,現有Linux主機,安裝了openssl,
證書文件:client.crt ,server.crt ,client.pem
openssl pkcs12 -export -in client.crt -out client.pfx ?-inkey client.pem -passin pass:123456
生成的pfx格式的證書,可以安裝在windows系統中,可以通過瀏覽器訪問,
程序中由于雙向認證,需要信任服務端證書,
把server.crt轉換為keystore格式
keytool -importkeystore -v ?-srckeystore client.pfx -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore client.keystore -deststoretype jks -deststorepass 123456
keytool -import -alias ca -trustcacerts -file server.crt -keystore client.keystore
把keystore設成客戶端信任證書即可實現雙向認證。
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.security.cert.X509Certificate;
import junit.framework.TestCase;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.junit.Before;
import org.junit.Test;
@SuppressWarnings("deprecation")
public class HttpsClient extends TestCase {
private String httpUrl = "https://127.0.0.1:443/TESTl/startupServlet";
// 客戶端密鑰庫
private String sslKeyStorePath;
private String sslKeyStorePassword;
private String sslKeyStoreType;
// 客戶端信任的證書
private String sslTrustStore;
private String sslTrustStorePassword;
@Before
public void setUp() {
sslKeyStorePath = "client.pfx";
sslKeyStorePassword = "123456";
sslKeyStoreType = "PKCS12"; // 密鑰庫類型,有JKS PKCS12等
sslTrustStore = "client.keystore";
sslTrustStorePassword = "123456";
System.setProperty("javax.net.ssl.keyStore", sslKeyStorePath);
System.setProperty("javax.net.ssl.keyStorePassword",
sslKeyStorePassword);
System.setProperty("javax.net.ssl.keyStoreType", sslKeyStoreType);
// 設置系統參數
System.setProperty("javax.net.ssl.trustStore", sslTrustStore);
System.setProperty("javax.net.ssl.trustStorePassword",
sslTrustStorePassword);
}
@Test
public void testHttpsClient() {
SSLContext sslContext = null;
try {
KeyStore kstore = KeyStore.getInstance("PKCS12");
kstore.load(new FileInputStream(sslKeyStorePath),
sslKeyStorePassword.toCharArray());
KeyManagerFactory keyFactory = KeyManagerFactory
.getInstance("sunx509");
keyFactory.init(kstore, sslKeyStorePassword.toCharArray());
KeyStore tstore = KeyStore.getInstance("jks");
tstore.load(new FileInputStream(sslTrustStore),
sslTrustStorePassword.toCharArray());
TrustManager[] tm;
TrustManagerFactory tmf = TrustManagerFactory
.getInstance("sunx509");
tmf.init(tstore);
tm = tmf.getTrustManagers();
sslContext = SSLContext.getInstance("SSL");
sslContext.init(keyFactory.getKeyManagers(), tm, null);
} catch (Exception e) {
e.printStackTrace();
}
try {
X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
@Override
public void verify(String arg0, SSLSocket arg1) throws IOException {}
@Override
public void verify(String arg0, String[] arg1, String[] arg2) throws SSLException {}
@Override
public void verify(String arg0, X509Certificate arg1) throws SSLException {}
};
HttpClient httpClient = new DefaultHttpClient();
SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext);
socketFactory.setHostnameVerifier(hostnameVerifier);
Scheme sch = new Scheme("https", 443, socketFactory);
httpClient.getConnectionManager().getSchemeRegistry().register(sch);
HttpPost httpPost = new HttpPost(httpUrl);
List nvps = new ArrayList();
//nvps.add(new BasicNameValuePair("pageSize", "1"));
//nvps.add(new BasicNameValuePair("name", null));
httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
HttpResponse httpResponse = httpClient.execute(httpPost);
String spt = System.getProperty("line.separator");
BufferedReader buffer = new BufferedReader(new InputStreamReader(
httpResponse.getEntity().getContent()));
StringBuffer stb = new StringBuffer();
String line = null;
while ((line = buffer.readLine()) != null) {
stb.append(line);
}
buffer.close();
String result = stb.toString();
System.out.println("result=" + result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
中間的重寫方法是由于證書中的主機名IP與實際訪問的不符合,這里是去除commonName的校驗。
聲明:本文為原創,轉載請注明出處。
總結
以上是生活随笔為你收集整理的用pfx证书java双向认证_把CA证书生成的crt的证书和pem的私钥转换成java能够使用的keystore和pcks12的证书,实现https双向认证...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面向对象-继承
- 下一篇: itextpdf添加表格元素_java使