http://www.cnblogs.com/tyjsjl/p/3359255.htmlphp
Tomcat 官方配置項java
生成CA簽名證書keystorenode
keytool -genkey -alias twt_server -keyalg RSA -keystore twt_server.jks -validity 3600 -storepass 123456
您的名字與姓氏是什麼? [Unknown]: android 您的組織單位名稱是什麼? [Unknown]: itian web 您的組織名稱是什麼? [Unknown]: itian算法 您所在的城市或區域名稱是什麼? [Unknown]: 北京 apache 您所在的省/市/自治區名稱是什麼? [Unknown]: 海淀 瀏覽器 該單位的雙字母國家/地區代碼是什麼? [Unknown]: cn tomcat CN=zhang, OU=zhang, O=zhang, L=xian, ST=shanxi, C=cn是否正確? [否]: y 輸入 <zhy_server> 的密鑰口令 (若是和密鑰庫口令相同, 按回車): |
而後生成cer證書
keytool -export -alias ca_server -file twt_server.cer -keystore twt_server.jks -storepass 123456
而後部署
<Connector SSLEnabled="true" acceptCount="100" clientAuth="false" disableUploadTimeout="true" enableLookups="true" keystoreFile="conf/CA/twt_server.jks" keystorePass="123456" maxSpareThreads="75" maxThreads="200" minSpareThreads="5" port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https" secure="true" sslProtocol="TLSv1.2" />
或者咱們新增一個新的服務
<Service name="MySSLService"> <Executor name="MySSLServiceTomcatThreadPool" namePrefix="MySSLService-exec-" maxThreads="200" minSpareThreads="4"/> <Connector connectionTimeout="20000" port="443" redirectPort="8443" maxPostSize="2048" #post請求最大數量,這裏是2M,若是是0,則沒有限制 maxThreads="200" executor="MySSLServiceTomcatThreadPool" #使用鏈接池 protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https" secure="true" SSLEnabled="true" keystoreType="JKS" #證書類型 keystoreFile="conf/CA/twt_server.jks" keystorePass="123456" clientAuth="false" sslProtocol="TLSv1.2" /> <Connector port="9009" protocol="AJP/1.3" redirectPort="8443" executor="MySSLServiceTomcatThreadPool" /> <Engine defaultHost="localhost" name="MySSLServiceEngine"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="ssl_access_log" suffix=".txt"/> </Host> </Engine> </Service>
這樣訪問,經過相應的url,如https就能訪問了.
這裏還有個問題,咱們生成的證書其實是JKS類型的證書,若是咱們使用PKCS12證書如何部署呢,PKCS12是互聯網標準,若是使用PKCS12,那麼java能夠更好地與其餘語言通訊。
JKS與PKCS12互相導入
p12(pfx) -> jks
keytool -importkeystore -srckeystore keystore.p12 -srcstoretype PKCS12 -deststoretype JKS -destkeystore keystore.jks
jks -> p12(pfx)
keytool -importkeystore -srckeystore keystore.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore keystore.p12
從jks裏面導出cert
keytool -export -alias cert0001 -keystore trust.jks -storepass 123456 -file cert0001.cer
將cert導入jks
keytool -import -v -alias cert001 -file cert001.cer -keystore trust.jks -storepass 123456 -noprompt
那麼,咱們能夠配置以下
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443" maxThreads="200" scheme="https" #使用https協議 secure="true" #使用安全連接 SSLEnabled="true" keystoreFile="conf/CA/keystore.p12" #指定PKCS12 keystore的位置 keystoreType="PKCS12" #證書類型修改成PKCS12便可 keystorePass="123456" clientAuth="false" #不去校驗客戶端 sslProtocol="TLS"/>
APR能夠提高Tomcat性能,那麼APR的Connector如何配置SSL呢
<Connector protocol="HTTP/1.1" port="443" maxHttpHeaderSize="8192" maxThreads="150" enableLookups="false" disableUploadTimeout="true" acceptCount="100" scheme="https" secure="true" SSLEnabled="true" SSLCertificateFile="conf/CA/rsa-private-key.pem" SSLCertificateKeyFile="conf/CA/self-signed-cert.crt" />
注意,APR的CA證書須要經過openSSL生成
openssl genrsa -out rsa-private-key.pem 1024 openssl req -new -x509 -nodes -sha1 -days 365 -key rsa-private-key.pem -out self-signed-cert.crt
1.生成服務器證書庫(爲了測試,我把有效期改成1天)
keytool -genkey -alias ca_server -keyalg RSA -keystore ca_server.jks -validity 1 -storepass 123456
注意:第一項提示姓名與姓氏時請輸入你的 域名
1.生成客戶端證書庫(爲了測試,我把有效期改成1天)
keytool -genkey -alias ca_client -keyalg RSA -storetype PKCS12 -keystore ca_client.pfx -validity 1 -storepass 123456
客戶端(客戶端須要使用PKCS12的密鑰,所以這裏咱們生成pfx密鑰證書)
2.將客戶端證書部分添加到服務端證書庫(讓服務器信任客戶端)
2.1.pkcs12不能直接導入服務器證書庫,須要導出cer證書,將證書導入到證書庫中
keytool -export -alias ca_client -keystore ca_client.pfx -storetype PKCS12 -storepass 123456 -rfc -file ca_client.cer
2.2而後將證書導入到服務端證書庫中
keytool -import -v -alias ca_client -file ca_client.cer -keystore ca_server.jks
3.配置Connector
在這裏,咱們爲了讓服務端證書庫和認證庫不要使用同一個keystore,咱們把ca_server.jks複製一份起名爲ca_trust.jks
此時配置修改以下
<Connector SSLEnabled="true" acceptCount="100" disableUploadTimeout="true" enableLookups="true" maxSpareThreads="75" maxThreads="200" minSpareThreads="5" port="8848" protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https" secure="true" clientAuth="true" #設置爲true,不然不回去驗證客戶端 sslProtocol="TLSv1.2" clientAuth="true" keystoreType="JKS" keystoreFile="conf/auth/ca_server.jks" keystorePass="123456" truststoreType="JKS" truststoreFile="conf/auth/ca_trust.jks" truststorePass="123456" />
4.使用瀏覽器訪問出現限制
而後咱們啓動Tomcat,使用瀏覽器訪問,發現不能訪問。說明咱們的設置已經生效了,那麼想讓瀏覽器能訪問該如何作呢?
首先,咱們須要安裝咱們的pfx證書,雙擊安裝,存儲區域位置請選擇【我的】,不然瀏覽器依然沒法訪問!
而後咱們訪問瀏覽器,就會出現證書選擇提示,選擇肯定,便能瀏覽網頁了。
5.Android雙向認證
雙向認證,以Android爲例子,Android支持PKCS12,BKS,AndroidCAStore,AndroidKeyStore
Name | Supported (API Levels) |
---|---|
AndroidCAStore | 14+(推薦) |
AndroidKeyStore | 18+ (推薦) |
BCPKCS12 | 1–8 (不建議考慮) |
BKS | 1+ |
BouncyCastle | 1+ |
PKCS12 | 1+ (推薦,PKCS12是互聯網標準) |
PKCS12-DEF | 1–8(不建議考慮) |
咱們這裏用網上的代碼,BKS作例子,固然,pkcs12能夠參考 android https經過加載pfx證書獲取數據
public void setCertificates(InputStream... certificates) { try { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null); int index = 0; for (InputStream certificate : certificates) { String certificateAlias = Integer.toString(index++); keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate)); try { if (certificate != null) certificate.close(); } catch (IOException e) { } } SSLContext sslContext = SSLContext.getInstance("TLS"); TrustManagerFactory trustManagerFactory = TrustManagerFactory. getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keyStore); //初始化keystore KeyStore clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType()); clientKeyStore.load(mContext.getAssets().open("ca_client.bks"), "123456".toCharArray()); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(clientKeyStore, "123456".toCharArray()); sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession sslsession) { if("localhost".equals(hostname)){ return true; } else { return false; } } }); } catch (Exception e) { e.printStackTrace(); } }
讀取cer證書
CertificateFactory certificatefactory = CertificateFactory .getInstance("X.509"); FileInputStream bais = new FileInputStream("srca.cer"); X509Certificate Cert = (X509Certificate) certificatefactory .generateCertificate(bais); bais.close(); System.out.println("版本號 " + Cert.getVersion()); System.out.println("序列號 " + Cert.getSerialNumber().toString(16)); System.out.println("全名 " + Cert.getSubjectDN()); System.out.println("簽發者全名n" + Cert.getIssuerDN()); System.out.println("有效期起始日 " + Cert.getNotBefore()); System.out.println("有效期截至日 " + Cert.getNotAfter()); System.out.println("簽名算法 " + Cert.getSigAlgName()); byte[] sig = Cert.getSignature(); System.out.println("簽名:" + new BigInteger(sig).toString(16)); PublicKey pk = Cert.getPublicKey(); System.out.println("PublicKey:" + Base64.getEncoder().encodeToString(pk.getEncoded()));
若是從密鑰庫讀取
String pass="080302"; String alias="mykey"; String name=".keystore"; FileInputStream in=new FileInputStream(name); KeyStore ks=KeyStore.getInstance("JKS"); ks.load(in,pass.toCharArray()); Certificate c=ks.getCertificate(alias); in.close(); System.out.println(c.toString( ));
PHP部分參閱