在
Java加密技術(八)中,咱們模擬了一個基於RSA非對稱加密網絡的安全通訊。如今咱們深度瞭解一下現有的安全網絡通訊——SSL。
咱們須要構建一個由CA機構簽發的有效證書,這裏咱們使用上文中生成的自簽名證書
zlex.cer
這裏,咱們將證書導入到咱們的密鑰庫。
- keytool -import -alias www.zlex.org -file d:/zlex.cer -keystore d:/zlex.keystore
keytool -import -alias www.zlex.org -file d:/zlex.cer -keystore d:/zlex.keystore
其中
-import表示
導入
-alias指定別名,這裏是
www.zlex.org
-file指定算法,這裏是
d:/zlex.cer
-keystore指定存儲位置,這裏是
d:/zlex.keystore
在這裏我使用的密碼爲
654321
控制檯輸出:
- 輸入keystore密碼:
- 再次輸入新密碼:
- 全部者:CN=www.zlex.org, OU=zlex, O=zlex, L=BJ, ST=BJ, C=CN
- 簽發人:CN=www.zlex.org, OU=zlex, O=zlex, L=BJ, ST=BJ, C=CN
- 序列號:4a1e48df
- 有效期: Thu May 28 16:18:39 CST 2009 至Wed Aug 26 16:18:39 CST 2009
- 證書指紋:
- MD5:19:CA:E6:36:E2:DF:AD:96:31:97:2F:A9:AD:FC:37:6A
- SHA1:49:88:30:59:29:45:F1:69:CA:97:A9:6D:8A:CF:08:D2:C3:D5:C0:C4
- 簽名算法名稱:SHA1withRSA
- 版本: 3
- 信任這個認證? [否]: y
- 認證已添加至keystore中
輸入keystore密碼:
再次輸入新密碼:
全部者:CN=www.zlex.org, OU=zlex, O=zlex, L=BJ, ST=BJ, C=CN
簽發人:CN=www.zlex.org, OU=zlex, O=zlex, L=BJ, ST=BJ, C=CN
序列號:4a1e48df
有效期: Thu May 28 16:18:39 CST 2009 至Wed Aug 26 16:18:39 CST 2009
證書指紋:
MD5:19:CA:E6:36:E2:DF:AD:96:31:97:2F:A9:AD:FC:37:6A
SHA1:49:88:30:59:29:45:F1:69:CA:97:A9:6D:8A:CF:08:D2:C3:D5:C0:C4
簽名算法名稱:SHA1withRSA
版本: 3
信任這個認證? [否]: y
認證已添加至keystore中
OK,最複雜的準備工做已經完成。
接下來咱們將域名
www.zlex.org定位到本機上。打開
C:\Windows\System32\drivers\etc\hosts文件,將
www.zlex.org綁定在本機上。在文件末尾追加
127.0.0.1 www.zlex.org。如今經過地址欄訪問
http://www.zlex.org,或者經過
ping命令,若是可以定位到本機,域名映射就搞定了。
如今,配置tomcat。先將
zlex.keystore拷貝到tomcat的conf目錄下,而後配置
server.xml。將以下內容加入配置文件
- <Connector
- SSLEnabled="true"
- URIEncoding="UTF-8"
- clientAuth="false"
- keystoreFile="conf/zlex.keystore"
- keystorePass="123456"
- maxThreads="150"
- port="443"
- protocol="HTTP/1.1"
- scheme="https"
- secure="true"
- sslProtocol="TLS" />
<Connector
SSLEnabled="true"
URIEncoding="UTF-8"
clientAuth="false"
keystoreFile="conf/zlex.keystore"
keystorePass="123456"
maxThreads="150"
port="443"
protocol="HTTP/1.1"
scheme="https"
secure="true"
sslProtocol="TLS" />
注意
clientAuth="false"測試階段,置爲
false,正式使用時建議使用
true。如今啓動tomcat,訪問
https://www.zlex.org/。
顯然,證書未能經過認證,這個時候你能夠選擇安裝證書(上文中的
zlex.cer文件就是證書),做爲
受信任的根證書頒發機構導入,再次重啓瀏覽器(IE,其餘瀏覽器對於域名www.zlex.org不支持本地方式訪問),訪問
https://www.zlex.org/,你會看到地址欄中會有個小鎖
![](http://static.javashuo.com/static/loading.gif)
,就說明安裝成功。全部的瀏覽器聯網操做已經在RSA加密解密系統的保護之下了。但彷佛咱們感覺不到。
這個時候不少人開始懷疑,若是咱們要手工作一個這樣的https的訪問是否是須要把瀏覽器的這些個功能都實現呢?不須要!
接着上篇內容,給出以下代碼實現:
- import java.io.FileInputStream;
- import java.security.KeyStore;
- import java.security.PrivateKey;
- import java.security.PublicKey;
- import java.security.Signature;
- import java.security.cert.Certificate;
- import java.security.cert.CertificateFactory;
- import java.security.cert.X509Certificate;
- import java.util.Date;
-
- import javax.crypto.Cipher;
- import javax.net.ssl.HttpsURLConnection;
- import javax.net.ssl.KeyManagerFactory;
- import javax.net.ssl.SSLContext;
- import javax.net.ssl.SSLSocketFactory;
- import javax.net.ssl.TrustManagerFactory;
-
- /**
- * 證書組件
- *
- * @author 樑棟
- * @version 1.0
- * @since 1.0
- */
- public abstract class CertificateCoder extends Coder {
-
- /**
- * Java密鑰庫(Java Key Store,JKS)KEY_STORE
- */
- public static final String KEY_STORE = "JKS";
-
- public static final String X509 = "X.509";
- public static final String SunX509 = "SunX509";
- public static final String SSL = "SSL";
-
- /**
- * 由KeyStore得到私鑰
- *
- * @param keyStorePath
- * @param alias
- * @param password
- * @return
- * @throws Exception
- */
- private static PrivateKey getPrivateKey(String keyStorePath, String alias,
- String password) throws Exception {
- KeyStore ks = getKeyStore(keyStorePath, password);
- PrivateKey key = (PrivateKey) ks.getKey(alias, password.toCharArray());
- return key;
- }
-
- /**
- * 由Certificate得到公鑰
- *
- * @param certificatePath
- * @return
- * @throws Exception
- */
- private static PublicKey getPublicKey(String certificatePath)
- throws Exception {
- Certificate certificate = getCertificate(certificatePath);
- PublicKey key = certificate.getPublicKey();
- return key;
- }
-
- /**
- * 得到Certificate
- *
- * @param certificatePath
- * @return
- * @throws Exception
- */
- private static Certificate getCertificate(String certificatePath)
- throws Exception {
- CertificateFactory certificateFactory = CertificateFactory
- .getInstance(X509);
- FileInputStream in = new FileInputStream(certificatePath);
-
- Certificate certificate = certificateFactory.generateCertificate(in);
- in.close();
-
- return certificate;
- }
-
- /**
- * 得到Certificate
- *
- * @param keyStorePath
- * @param alias
- * @param password
- * @return
- * @throws Exception
- */
- private static Certificate getCertificate(String keyStorePath,
- String alias, String password) throws Exception {
- KeyStore ks = getKeyStore(keyStorePath, password);
- Certificate certificate = ks.getCertificate(alias);
-
- return certificate;
- }
-
- /**
- * 得到KeyStore
- *
- * @param keyStorePath
- * @param password
- * @return
- * @throws Exception
- */
- private static KeyStore getKeyStore(String keyStorePath, String password)
- throws Exception {
- FileInputStream is = new FileInputStream(keyStorePath);
- KeyStore ks = KeyStore.getInstance(KEY_STORE);
- ks.load(is, password.toCharArray());
- is.close();
- return ks;
- }
-
- /**
- * 私鑰加密
- *
- * @param data
- * @param keyStorePath
- * @param alias
- * @param password
- * @return
- * @throws Exception
- */
- public static byte[] encryptByPrivateKey(byte[] data, String keyStorePath,
- String alias, String password) throws Exception {
- // 取得私鑰
- PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);
-
- // 對數據加密
- Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
- cipher.init(Cipher.ENCRYPT_MODE, privateKey);
-
- return cipher.doFinal(data);
-
- }
-
- /**
- * 私鑰解密
- *
- * @param data
- * @param keyStorePath
- * @param alias
- * @param password
- * @return
- * @throws Exception
- */
- public static byte[] decryptByPrivateKey(byte[] data, String keyStorePath,
- String alias, String password) throws Exception {
- // 取得私鑰
- PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);
-
- // 對數據加密
- Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
- cipher.init(Cipher.DECRYPT_MODE, privateKey);
-
- return cipher.doFinal(data);
-
- }
-
- /**
- * 公鑰加密
- *
- * @param data
- * @param certificatePath
- * @return
- * @throws Exception
- */
- public static byte[] encryptByPublicKey(byte[] data, String certificatePath)
- throws Exception {
-
- // 取得公鑰
- PublicKey publicKey = getPublicKey(certificatePath);
- // 對數據加密
- Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
- cipher.init(Cipher.ENCRYPT_MODE, publicKey);
-
- return cipher.doFinal(data);
-
- }
-
- /**
- * 公鑰解密
- *
- * @param data
- * @param certificatePath
- * @return
- * @throws Exception
- */
- public static byte[] decryptByPublicKey(byte[] data, String certificatePath)
- throws Exception {
- // 取得公鑰
- PublicKey publicKey = getPublicKey(certificatePath);
-
- // 對數據加密
- Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
- cipher.init(Cipher.DECRYPT_MODE, publicKey);
-
- return cipher.doFinal(data);
-
- }
-
- /**
- * 驗證Certificate
- *
- * @param certificatePath
- * @return
- */
- public static boolean verifyCertificate(String certificatePath) {
- return verifyCertificate(new Date(), certificatePath);
- }
-
- /**
- * 驗證Certificate是否過時或無效
- *
- * @param date
- * @param certificatePath
- * @return
- */
- public static boolean verifyCertificate(Date date, String certificatePath) {
- boolean status = true;
- try {
- // 取得證書
- Certificate certificate = getCertificate(certificatePath);
- // 驗證證書是否過時或無效
- status = verifyCertificate(date, certificate);
- } catch (Exception e) {
- status = false;
- }
- return status;
- }
-
- /**
- * 驗證證書是否過時或無效
- *
- * @param date
- * @param certificate
- * @return
- */
- private static boolean verifyCertificate(Date date, Certificate certificate) {
- boolean status = true;
- try {
- X509Certificate x509Certificate = (X509Certificate) certificate;
- x509Certificate.checkValidity(date);
- } catch (Exception e) {
- status = false;
- }
- return status;
- }
-
- /**
- * 簽名
- *
- * @param keyStorePath
- * @param alias
- * @param password
- *
- * @return
- * @throws Exception
- */
- public static String sign(byte[] sign, String keyStorePath, String alias,
- String password) throws Exception {
- // 得到證書
- X509Certificate x509Certificate = (X509Certificate) getCertificate(
- keyStorePath, alias, password);
- // 獲取私鑰
- KeyStore ks = getKeyStore(keyStorePath, password);
- // 取得私鑰
- PrivateKey privateKey = (PrivateKey) ks.getKey(alias, password
- .toCharArray());
-
- // 構建簽名
- Signature signature = Signature.getInstance(x509Certificate
- .getSigAlgName());
- signature.initSign(privateKey);
- signature.update(sign);
- return encryptBASE64(signature.sign());
- }
-
- /**
- * 驗證簽名
- *
- * @param data
- * @param sign
- * @param certificatePath
- * @return
- * @throws Exception
- */
- public static boolean verify(byte[] data, String sign,
- String certificatePath) throws Exception {
- // 得到證書
- X509Certificate x509Certificate = (X509Certificate) getCertificate(certificatePath);
- // 得到公鑰
- PublicKey publicKey = x509Certificate.getPublicKey();
- // 構建簽名
- Signature signature = Signature.getInstance(x509Certificate
- .getSigAlgName());
- signature.initVerify(publicKey);
- signature.update(data);
-
- return signature.verify(decryptBASE64(sign));
-
- }
-
- /**
- * 驗證Certificate
- *
- * @param keyStorePath
- * @param alias
- * @param password
- * @return
- */
- public static boolean verifyCertificate(Date date, String keyStorePath,
- String alias, String password) {
- boolean status = true;
- try {
- Certificate certificate = getCertificate(keyStorePath, alias,
- password);
- status = verifyCertificate(date, certificate);
- } catch (Exception e) {
- status = false;
- }
- return status;
- }
-
- /**
- * 驗證Certificate
- *
- * @param keyStorePath
- * @param alias
- * @param password
- * @return
- */
- public static boolean verifyCertificate(String keyStorePath, String alias,
- String password) {
- return verifyCertificate(new Date(), keyStorePath, alias, password);
- }
-
- /**
- * 得到SSLSocektFactory
- *
- * @param password
- * 密碼
- * @param keyStorePath
- * 密鑰庫路徑
- *
- * @param trustKeyStorePath
- * 信任庫路徑
- * @return
- * @throws Exception
- */
- private static SSLSocketFactory getSSLSocketFactory(String password,
- String keyStorePath, String trustKeyStorePath) throws Exception {
- // 初始化密鑰庫
- KeyManagerFactory keyManagerFactory = KeyManagerFactory
- .getInstance(SunX509);
- KeyStore keyStore = getKeyStore(keyStorePath, password);
- keyManagerFactory.init(keyStore, password.toCharArray());
-
- // 初始化信任庫
- TrustManagerFactory trustManagerFactory = TrustManagerFactory
- .getInstance(SunX509);
- KeyStore trustkeyStore = getKeyStore(trustKeyStorePath, password);
- trustManagerFactory.init(trustkeyStore);
-
- // 初始化SSL上下文
- SSLContext ctx = SSLContext.getInstance(SSL);
- ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory
- .getTrustManagers(), null);
- SSLSocketFactory sf = ctx.getSocketFactory();
-
- return sf;
- }
-
- /**
- * 爲HttpsURLConnection配置SSLSocketFactory
- *
- * @param conn
- * HttpsURLConnection
- * @param password
- * 密碼
- * @param keyStorePath
- * 密鑰庫路徑
- *
- * @param trustKeyStorePath
- * 信任庫路徑
- * @throws Exception
- */
- public static void configSSLSocketFactory(HttpsURLConnection conn,
- String password, String keyStorePath, String trustKeyStorePath)
- throws Exception {
- conn.setSSLSocketFactory(getSSLSocketFactory(password, keyStorePath,
- trustKeyStorePath));
- }
- }
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;
import javax.crypto.Cipher;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
/**
* 證書組件
*
* @author 樑棟
* @version 1.0
* @since 1.0
*/
public abstract class CertificateCoder extends Coder {
/**
* Java密鑰庫(Java Key Store,JKS)KEY_STORE
*/
public static final String KEY_STORE = "JKS";
public static final String X509 = "X.509";
public static final String SunX509 = "SunX509";
public static final String SSL = "SSL";
/**
* 由KeyStore得到私鑰
*
* @param keyStorePath
* @param alias
* @param password
* @return
* @throws Exception
*/
private static PrivateKey getPrivateKey(String keyStorePath, String alias,
String password) throws Exception {
KeyStore ks = getKeyStore(keyStorePath, password);
PrivateKey key = (PrivateKey) ks.getKey(alias, password.toCharArray());
return key;
}
/**
* 由Certificate得到公鑰
*
* @param certificatePath
* @return
* @throws Exception
*/
private static PublicKey getPublicKey(String certificatePath)
throws Exception {
Certificate certificate = getCertificate(certificatePath);
PublicKey key = certificate.getPublicKey();
return key;
}
/**
* 得到Certificate
*
* @param certificatePath
* @return
* @throws Exception
*/
private static Certificate getCertificate(String certificatePath)
throws Exception {
CertificateFactory certificateFactory = CertificateFactory
.getInstance(X509);
FileInputStream in = new FileInputStream(certificatePath);
Certificate certificate = certificateFactory.generateCertificate(in);
in.close();
return certificate;
}
/**
* 得到Certificate
*
* @param keyStorePath
* @param alias
* @param password
* @return
* @throws Exception
*/
private static Certificate getCertificate(String keyStorePath,
String alias, String password) throws Exception {
KeyStore ks = getKeyStore(keyStorePath, password);
Certificate certificate = ks.getCertificate(alias);
return certificate;
}
/**
* 得到KeyStore
*
* @param keyStorePath
* @param password
* @return
* @throws Exception
*/
private static KeyStore getKeyStore(String keyStorePath, String password)
throws Exception {
FileInputStream is = new FileInputStream(keyStorePath);
KeyStore ks = KeyStore.getInstance(KEY_STORE);
ks.load(is, password.toCharArray());
is.close();
return ks;
}
/**
* 私鑰加密
*
* @param data
* @param keyStorePath
* @param alias
* @param password
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String keyStorePath,
String alias, String password) throws Exception {
// 取得私鑰
PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);
// 對數據加密
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 私鑰解密
*
* @param data
* @param keyStorePath
* @param alias
* @param password
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] data, String keyStorePath,
String alias, String password) throws Exception {
// 取得私鑰
PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);
// 對數據加密
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 公鑰加密
*
* @param data
* @param certificatePath
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String certificatePath)
throws Exception {
// 取得公鑰
PublicKey publicKey = getPublicKey(certificatePath);
// 對數據加密
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 公鑰解密
*
* @param data
* @param certificatePath
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] data, String certificatePath)
throws Exception {
// 取得公鑰
PublicKey publicKey = getPublicKey(certificatePath);
// 對數據加密
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 驗證Certificate
*
* @param certificatePath
* @return
*/
public static boolean verifyCertificate(String certificatePath) {
return verifyCertificate(new Date(), certificatePath);
}
/**
* 驗證Certificate是否過時或無效
*
* @param date
* @param certificatePath
* @return
*/
public static boolean verifyCertificate(Date date, String certificatePath) {
boolean status = true;
try {
// 取得證書
Certificate certificate = getCertificate(certificatePath);
// 驗證證書是否過時或無效
status = verifyCertificate(date, certificate);
} catch (Exception e) {
status = false;
}
return status;
}
/**
* 驗證證書是否過時或無效
*
* @param date
* @param certificate
* @return
*/
private static boolean verifyCertificate(Date date, Certificate certificate) {
boolean status = true;
try {
X509Certificate x509Certificate = (X509Certificate) certificate;
x509Certificate.checkValidity(date);
} catch (Exception e) {
status = false;
}
return status;
}
/**
* 簽名
*
* @param keyStorePath
* @param alias
* @param password
*
* @return
* @throws Exception
*/
public static String sign(byte[] sign, String keyStorePath, String alias,
String password) throws Exception {
// 得到證書
X509Certificate x509Certificate = (X509Certificate) getCertificate(
keyStorePath, alias, password);
// 獲取私鑰
KeyStore ks = getKeyStore(keyStorePath, password);
// 取得私鑰
PrivateKey privateKey = (PrivateKey) ks.getKey(alias, password
.toCharArray());
// 構建簽名
Signature signature = Signature.getInstance(x509Certificate
.getSigAlgName());
signature.initSign(privateKey);
signature.update(sign);
return encryptBASE64(signature.sign());
}
/**
* 驗證簽名
*
* @param data
* @param sign
* @param certificatePath
* @return
* @throws Exception
*/
public static boolean verify(byte[] data, String sign,
String certificatePath) throws Exception {
// 得到證書
X509Certificate x509Certificate = (X509Certificate) getCertificate(certificatePath);
// 得到公鑰
PublicKey publicKey = x509Certificate.getPublicKey();
// 構建簽名
Signature signature = Signature.getInstance(x509Certificate
.getSigAlgName());
signature.initVerify(publicKey);
signature.update(data);
return signature.verify(decryptBASE64(sign));
}
/**
* 驗證Certificate
*
* @param keyStorePath
* @param alias
* @param password
* @return
*/
public static boolean verifyCertificate(Date date, String keyStorePath,
String alias, String password) {
boolean status = true;
try {
Certificate certificate = getCertificate(keyStorePath, alias,
password);
status = verifyCertificate(date, certificate);
} catch (Exception e) {
status = false;
}
return status;
}
/**
* 驗證Certificate
*
* @param keyStorePath
* @param alias
* @param password
* @return
*/
public static boolean verifyCertificate(String keyStorePath, String alias,
String password) {
return verifyCertificate(new Date(), keyStorePath, alias, password);
}
/**
* 得到SSLSocektFactory
*
* @param password
* 密碼
* @param keyStorePath
* 密鑰庫路徑
*
* @param trustKeyStorePath
* 信任庫路徑
* @return
* @throws Exception
*/
private static SSLSocketFactory getSSLSocketFactory(String password,
String keyStorePath, String trustKeyStorePath) throws Exception {
// 初始化密鑰庫
KeyManagerFactory keyManagerFactory = KeyManagerFactory
.getInstance(SunX509);
KeyStore keyStore = getKeyStore(keyStorePath, password);
keyManagerFactory.init(keyStore, password.toCharArray());
// 初始化信任庫
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance(SunX509);
KeyStore trustkeyStore = getKeyStore(trustKeyStorePath, password);
trustManagerFactory.init(trustkeyStore);
// 初始化SSL上下文
SSLContext ctx = SSLContext.getInstance(SSL);
ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory
.getTrustManagers(), null);
SSLSocketFactory sf = ctx.getSocketFactory();
return sf;
}
/**
* 爲HttpsURLConnection配置SSLSocketFactory
*
* @param conn
* HttpsURLConnection
* @param password
* 密碼
* @param keyStorePath
* 密鑰庫路徑
*
* @param trustKeyStorePath
* 信任庫路徑
* @throws Exception
*/
public static void configSSLSocketFactory(HttpsURLConnection conn,
String password, String keyStorePath, String trustKeyStorePath)
throws Exception {
conn.setSSLSocketFactory(getSSLSocketFactory(password, keyStorePath,
trustKeyStorePath));
}
}
增長了
configSSLSocketFactory方法供外界調用,該方法爲HttpsURLConnection配置了SSLSocketFactory。當HttpsURLConnection配置了SSLSocketFactory後,咱們就能夠經過HttpsURLConnection的getInputStream、getOutputStream,像往常使用HttpURLConnection作操做了。尤爲要說明一點,未配置SSLSocketFactory前,HttpsURLConnection的getContentLength()得到值永遠都是
-1。
給出相應測試類:
- import static org.junit.Assert.*;
-
- import java.io.DataInputStream;
- import java.io.InputStream;
- import java.net.URL;
-
- import javax.net.ssl.HttpsURLConnection;
-
- import org.junit.Test;
-
- /**
- *
- * @author 樑棟
- * @version 1.0
- * @since 1.0
- */
- public class CertificateCoderTest {
- private String password = "123456";
- private String alias = "www.zlex.org";
- private String certificatePath = "d:/zlex.cer";
- private String keyStorePath = "d:/zlex.keystore";
- private String clientKeyStorePath = "d:/zlex-client.keystore";
- private String clientPassword = "654321";
-
- @Test
- public void test() throws Exception {
- System.err.println("公鑰加密——私鑰解密");
- String inputStr = "Ceritifcate";
- byte[] data = inputStr.getBytes();
-
- byte[] encrypt = CertificateCoder.encryptByPublicKey(data,
- certificatePath);
-
- byte[] decrypt = CertificateCoder.decryptByPrivateKey(encrypt,
- keyStorePath, alias, password);
- String outputStr = new String(decrypt);
-
- System.err.println("加密前: " + inputStr + "\n\r" + "解密後: " + outputStr);
-
- // 驗證數據一致
- assertArrayEquals(data, decrypt);
-
- // 驗證證書有效
- assertTrue(CertificateCoder.verifyCertificate(certificatePath));
-
- }
-
- @Test
- public void testSign() throws Exception {
- System.err.println("私鑰加密——公鑰解密");
-
- String inputStr = "sign";
- byte[] data = inputStr.getBytes();
-
- byte[] encodedData = CertificateCoder.encryptByPrivateKey(data,
- keyStorePath, alias, password);
-
- byte[] decodedData = CertificateCoder.decryptByPublicKey(encodedData,
- certificatePath);
-
- String outputStr = new String(decodedData);
- System.err.println("加密前: " + inputStr + "\n\r" + "解密後: " + outputStr);
- assertEquals(inputStr, outputStr);
-
- System.err.println("私鑰簽名——公鑰驗證簽名");
- // 產生簽名
- String sign = CertificateCoder.sign(encodedData, keyStorePath, alias,
- password);
- System.err.println("簽名:\r" + sign);
-
- // 驗證簽名
- boolean status = CertificateCoder.verify(encodedData, sign,
- certificatePath);
- System.err.println("狀態:\r" + status);
- assertTrue(status);
-
- }
-
- @Test
- public void testHttps() throws Exception {
- URL url = new URL("https://www.zlex.org/examples/");
- HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
-
- conn.setDoInput(true);
- conn.setDoOutput(true);
-
- CertificateCoder.configSSLSocketFactory(conn, clientPassword,
- clientKeyStorePath, clientKeyStorePath);
-
- InputStream is = conn.getInputStream();
-
- int length = conn.getContentLength();
-
- DataInputStream dis = new DataInputStream(is);
- byte[] data = new byte[length];
- dis.readFully(data);
-
- dis.close();
- System.err.println(new String(data));
- conn.disconnect();
- }
- }
import static org.junit.Assert.*;
import java.io.DataInputStream;
import java.io.InputStream;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import org.junit.Test;
/**
*
* @author 樑棟
* @version 1.0
* @since 1.0
*/
public class CertificateCoderTest {
private String password = "123456";
private String alias = "www.zlex.org";
private String certificatePath = "d:/zlex.cer";
private String keyStorePath = "d:/zlex.keystore";
private String clientKeyStorePath = "d:/zlex-client.keystore";
private String clientPassword = "654321";
@Test
public void test() throws Exception {
System.err.println("公鑰加密——私鑰解密");
String inputStr = "Ceritifcate";
byte[] data = inputStr.getBytes();
byte[] encrypt = CertificateCoder.encryptByPublicKey(data,
certificatePath);
byte[] decrypt = CertificateCoder.decryptByPrivateKey(encrypt,
keyStorePath, alias, password);
String outputStr = new String(decrypt);
System.err.println("加密前: " + inputStr + "\n\r" + "解密後: " + outputStr);
// 驗證數據一致
assertArrayEquals(data, decrypt);
// 驗證證書有效
assertTrue(CertificateCoder.verifyCertificate(certificatePath));
}
@Test
public void testSign() throws Exception {
System.err.println("私鑰加密——公鑰解密");
String inputStr = "sign";
byte[] data = inputStr.getBytes();
byte[] encodedData = CertificateCoder.encryptByPrivateKey(data,
keyStorePath, alias, password);
byte[] decodedData = CertificateCoder.decryptByPublicKey(encodedData,
certificatePath);
String outputStr = new String(decodedData);
System.err.println("加密前: " + inputStr + "\n\r" + "解密後: " + outputStr);
assertEquals(inputStr, outputStr);
System.err.println("私鑰簽名——公鑰驗證簽名");
// 產生簽名
String sign = CertificateCoder.sign(encodedData, keyStorePath, alias,
password);
System.err.println("簽名:\r" + sign);
// 驗證簽名
boolean status = CertificateCoder.verify(encodedData, sign,
certificatePath);
System.err.println("狀態:\r" + status);
assertTrue(status);
}
@Test
public void testHttps() throws Exception {
URL url = new URL("https://www.zlex.org/examples/");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
CertificateCoder.configSSLSocketFactory(conn, clientPassword,
clientKeyStorePath, clientKeyStorePath);
InputStream is = conn.getInputStream();
int length = conn.getContentLength();
DataInputStream dis = new DataInputStream(is);
byte[] data = new byte[length];
dis.readFully(data);
dis.close();
System.err.println(new String(data));
conn.disconnect();
}
}
注意
testHttps方法,幾乎和咱們往常作HTTP訪問沒有差異,咱們來看控制檯輸出:
- <!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
- <HTML><HEAD><TITLE>Apache Tomcat Examples</TITLE>
- <META http-equiv=Content-Type content="text/html">
- </HEAD>
- <BODY>
- <P>
- <H3>Apache Tomcat Examples</H3>
- <P></P>
- <ul>
- <li><a href="servlets">Servlets examples</a></li>
- <li><a href="jsp">JSP Examples</a></li>
- </ul>
- </BODY></HTML>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>Apache Tomcat Examples</TITLE>
<META http-equiv=Content-Type content="text/html">
</HEAD>
<BODY>
<P>
<H3>Apache Tomcat Examples</H3>
<P></P>
<ul>
<li><a href="servlets">Servlets examples</a></li>
<li><a href="jsp">JSP Examples</a></li>
</ul>
</BODY></HTML>
經過瀏覽器直接訪問
https://www.zlex.org/examples/你也會得到上述內容。也就是說應用甲方做爲服務器構建tomcat服務,乙方能夠經過上述方式訪問甲方受保護的SSL應用,而且不須要考慮具體的加密解密問題。甲乙雙方能夠通過相應配置,經過雙方的tomcat配置有效的SSL服務,簡化上述代碼實現,徹底經過證書配置完成SSL雙向認證!