Java,SSL/TLS协议,单向和双向认证,命令制作及代码生成证书
概念
SSL/TLS协议
SSL(Secure Sockets Layer),安全套接字协议,是为网络通信提供安全及数据完整性的一种安全协议。SSL主要是使用公开密钥体制和X.509数字证书技术保护信息传输的机密性和完整性,它不能保证信息的不可抵赖性,主要适用于点对点之间的信息传输。
TLS(Transport Layer Security),传输层安全,是IETF在SSL3.0的基础上设计的协议,它是SSL协议的升级版。两者差别极小,可以理解为TLS是 SSL3.1。
TLS与SSL都是在传输层与应用层之间对网络连接进行加密。
单向认证VS双向认证
单向认证,服务端部署SSL证书就行,任何用户都可以去访问(IP被限制除外等),只是服务端提供了身份认证。
双向认证,服务端部署SSL证书,也需要客户端提供身份认证,只有服务端允许的客户端才能访问,安全性相对于要高一些。
SSL单向认证过程、SSL双向认证过程
制作证书
命令制作用于SSL/TSL的证书
#1、服务器端===>生成自签名证书
keytool -genkey -dname "CN=localhost" -keysize 2048 -alias server -keyalg RSA -keystore d:/server.jks -keypass 123456 -storepass 123456 -validity 36500
#2、服务器端===>从服务器端证书秘钥库中导出Cer证书
keytool -export -alias server -keystore d:/server.jks -storepass 123456 -file d:/server.cer
#3、客户端==>生成自签名证书
keytool -genkey -dname "CN=localhost.client1" -keysize 2048 -alias client1 -keyalg RSA -keystore d:/client1.jks -keypass 123456 -storepass 123456 -validity 36500
#4、客户端==>从服务器端证书秘钥库中导出Cer证书
keytool -export -alias client1 -keystore d:/client1.jks -storepass 123456 -file d:/client1.cer
#5、客户端==>将客户端证书导入到服务器端证书秘钥库
keytool -import -trustcacerts -alias server -file d:/server.cer -keystore d:/client1.jks -storepass 123456
# 6、服务器端==>将服务器端证书导入到客户端证书秘钥库
keytool -import -trustcacerts -alias client1 -file d:/client1.cer -keystore d:/server.jks -storepass 123456
# ****查看颁发证书
keytool -list -keystore D://server.jks
keytool -list -rfc -keystore d:/server.jks -storepass 123456
keytool -list -keystore D://client1.jks
keytool -list -rfc -keystore d:/client1.jks -storepass 123456
代码制作用于SSL/TSL的证书
说明:与命令制作一致,内容必须参考:生成自签名证书、生成签名证书,注意没有给出maven相应的坐标,这次补上。
Maven(pom.xml)
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15to18</artifactId>
<version>1.70</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15to18</artifactId>
<version>1.70</version>
</dependency>
制作证书代码:
package com.what21.netty01.demo01.cert2;
import com.what21.netty01.demo01.cert.CreateDataCertificateStore;
import com.what21.netty01.demo01.cert.IssueCertificate;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
public class KeyStoreTest {
public static void main(String[] args) {
// ===============================================================================//
// 1、服务器端===>生成自签名证书
// ===============================================================================//
int keyLen = 2048;
String alias = "server";
String storePasswd = "123456";
String trustPasswd = "123456";
// 注意顺序
String fullDN = "CN=localhost";
String storePath = "D://localhost_server.jks";
try {
OutputStream storeOutput = new FileOutputStream(storePath);
CreateDataCertificateStore.generateKeyStore(keyLen, alias, storePasswd, trustPasswd, fullDN, 10, storeOutput);
} catch (Exception e) {
e.printStackTrace();
}
// ===============================================================================//
// 2、服务器端===>从服务器端证书秘钥库中导出Cer证书
// ===============================================================================//
KeyStoreUtils.KeyStoreParam keyStoreParam = new KeyStoreUtils.KeyStoreParam();
keyStoreParam.setStorePath(storePath);
keyStoreParam.setStorePasswd(storePasswd);
keyStoreParam.setAlias(alias);
keyStoreParam.setTrustPasswd(trustPasswd);
KeyStoreUtils.KeyStoreEntry keyStoreEntry = KeyStoreUtils.readToKeyStoreEntry(keyStoreParam);
CertUtils.generateCert(keyStoreEntry, "D://localhost_server.cer");
// ===============================================================================//
// 3、客户端==>使用服务器端签名证书生成客户端证书
// ===============================================================================//
KeyStore.PrivateKeyEntry rootPrivateKeyEntry = null;
try {
rootPrivateKeyEntry = IssueCertificate.getRootPrivateKey(storePath, storePasswd, alias, trustPasswd);
} catch (Exception e) {
e.printStackTrace();
}
String clientAlias = "client1";
String subjects = "CN=localhost.client1";
String signTrustPasswd = "123456";
int validityYears = 10;
String trustPath = "d:/localhost_client1.jks";
try {
IssueCertificate.issueCertificate(rootPrivateKeyEntry, clientAlias, subjects, signTrustPasswd, validityYears, trustPath);
} catch (Exception e) {
e.printStackTrace();
}
// ===============================================================================//
// 4、客户端==>从服务器端证书秘钥库中导出Cer证书
// ===============================================================================//
KeyStoreUtils.KeyStoreParam clientKeyStoreParam = new KeyStoreUtils.KeyStoreParam();
clientKeyStoreParam.setStorePath(trustPath);
clientKeyStoreParam.setStorePasswd(signTrustPasswd);
clientKeyStoreParam.setAlias(clientAlias);
clientKeyStoreParam.setTrustPasswd(signTrustPasswd);
KeyStoreUtils.KeyStoreEntry clientKeyStoreEntry = KeyStoreUtils.readToKeyStoreEntry(clientKeyStoreParam);
CertUtils.generateCert(clientKeyStoreEntry, "D://localhost_client1.cer");
// ===============================================================================//
// 5、客户端==>将客户端证书导入到服务器端证书秘钥库
// ===============================================================================//
Certificate clientCertificate = CertUtils.readCert("D://localhost_client1.cer");
try {
KeyStoreUtils.importToKeyStore(storePath, storePasswd, "client1", clientCertificate);
} catch (Exception e) {
e.printStackTrace();
}
// keytool -list -keystore D://localhost_server.jks
// keytool -list -rfc -keystore D://localhost_server.jks -storepass 123456
// ===============================================================================//
// 6、服务器端==>将服务器端证书导入到客户端证书秘钥库
// ===============================================================================//
Certificate serverCertificate = CertUtils.readCert("D://localhost_server.cer");
try {
KeyStoreUtils.importToKeyStore(storePath, signTrustPasswd, "server", serverCertificate);
} catch (Exception e) {
e.printStackTrace();
}
// keytool -list -keystore D://localhost_client1.jks
// keytool -list -rfc -keystore D://localhost_client1.jks -storepass 123456
// ===============================================================================//
// The end
// ===============================================================================//
}
}
依赖如下的工具类,没有找到,请到关联的文章中找~
其他工具类:
package com.what21.netty01.demo01.cert2;
import lombok.Data;
import sun.misc.BASE64Encoder;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
public class KeyStoreUtils {
/**
* @param storePath 秘钥库文件路径
* @param storePasswd 秘钥库密码
* @param alias 证书别名
* @param trustPasswd 证书密码
* @return
* @throws Exception
*/
public static KeyStoreEntry readToKeyStoreEntry(String storePath, String storePasswd, String alias, String trustPasswd)
throws Exception {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(storePath), storePasswd.toCharArray());
PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, trustPasswd.toCharArray());
PublicKey publicKey = keyStore.getCertificate(alias).getPublicKey();
Certificate certificate = keyStore.getCertificate(alias);
BASE64Encoder encoder = new BASE64Encoder();
String privateKeyEncoded = encoder.encode(privateKey.getEncoded());
String publicKeyEncoded = encoder.encode(publicKey.getEncoded());
KeyStoreEntry keyStoreEntry = new KeyStoreEntry();
keyStoreEntry.setKeyStore(keyStore);
keyStoreEntry.setPrivateKey(privateKey);
keyStoreEntry.setPublicKey(publicKey);
keyStoreEntry.setCertificate(certificate);
keyStoreEntry.setPrivateKeyEncoded(privateKeyEncoded);
keyStoreEntry.setPublicKeyEncoded(publicKeyEncoded);
return keyStoreEntry;
}
/**
* @param storePath
* @param storePasswd
* @param certAlias
* @param certificate
* @throws Exception
*/
public static void importToKeyStore(String storePath, String storePasswd, String certAlias, Certificate certificate)
throws Exception {
KeyStore keyStore = KeyStore.getInstance("JKS");
FileInputStream keyStoreInput = new FileInputStream(storePath);
keyStore.load(keyStoreInput, storePasswd.toCharArray());
keyStoreInput.close();
if (!keyStore.containsAlias(certAlias)) {
keyStore.setCertificateEntry(certAlias, certificate);
FileOutputStream keyStoreOutput = new FileOutputStream(storePath);
keyStore.store(keyStoreOutput, storePasswd.toCharArray());
keyStoreOutput.close();
}
}
@Data
public static class KeyStoreEntry {
private KeyStore keyStore;
private PrivateKey privateKey;
private PublicKey publicKey;
private Certificate certificate;
private String privateKeyEncoded;
private String publicKeyEncoded;
}
@Data
public static class KeyStoreParam {
public String storePath = "d:/server.jks";
public String storePasswd = "123456";
public String alias = "server";
public String trustPasswd = "123456";
}
/**
* @param keyStoreParam
* @return
*/
public static KeyStoreEntry readToKeyStoreEntry(KeyStoreParam keyStoreParam) {
try {
return readToKeyStoreEntry(keyStoreParam.getStorePath(), keyStoreParam.getStorePasswd(),
keyStoreParam.getAlias(), keyStoreParam.getTrustPasswd());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* @return
*/
public static KeyStoreEntry readToKeyStoreEntry() {
String storePath = "d:/server.jks";
String storePasswd = "123456";
String alias = "server";
String trustPasswd = "123456";
try {
return readToKeyStoreEntry(storePath, storePasswd, alias, trustPasswd);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
package com.what21.netty01.demo01.cert2;
import java.io.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
/**
* CER = CRT证书的微软型式
*/
public class CertUtils {
/**
* 打印证书内容
*
* @param x509Certificate
* @return
*/
public static Certificate printInfo(X509Certificate x509Certificate) {
System.out.println("读取Cer证书信息...");
System.out.println("x509Certificate_SerialNumber_序列号___:" + x509Certificate.getSerialNumber());
System.out.println("版本号:" + x509Certificate.getVersion());
System.out.println("序列号:" + x509Certificate.getSerialNumber().toString(16));
System.out.println("主体名:" + x509Certificate.getSubjectDN());
System.out.println("签发者:" + x509Certificate.getIssuerDN());
System.out.println("有效期:" + x509Certificate.getNotBefore());
System.out.println("截止日期:" + x509Certificate.getNotAfter());
System.out.println("签名算法:" + x509Certificate.getSigAlgName());
System.out.println("x509Certificate_getIssuerDN_发布方标识名___:" + x509Certificate.getIssuerDN());
System.out.println("x509Certificate_getSubjectDN_主体标识___:" + x509Certificate.getSubjectDN());
System.out.println("x509Certificate_getSigAlgOID_证书算法OID字符串___:" + x509Certificate.getSigAlgOID());
System.out.println("x509Certificate_getNotBefore_证书有效期___:" + x509Certificate.getNotAfter());
System.out.println("x509Certificate_getSigAlgName_签名算法___:" + x509Certificate.getSigAlgName());
System.out.println("x509Certificate_getVersion_版本号___:" + x509Certificate.getVersion());
System.out.println("x509Certificate_getPublicKey_公钥___:" + x509Certificate.getPublicKey());
return x509Certificate;
}
/**
* @param keyStoreEntry
* @param cerFile
*/
public static void generateCert(KeyStoreUtils.KeyStoreEntry keyStoreEntry, String cerFile) {
try {
FileOutputStream outputStream = new FileOutputStream(cerFile);
outputStream.write(keyStoreEntry.getCertificate().getEncoded());
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param certPath
* @return
*/
public static Certificate readCert(String certPath) {
Certificate certificate = null;
try {
CertificateFactory factory = CertificateFactory.getInstance("X.509");
FileInputStream inputStream = new FileInputStream(certPath);
certificate = factory.generateCertificate(inputStream);
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
return certificate;
}
/**
* @param args
*/
public static void main(String[] args) {
KeyStoreUtils.KeyStoreEntry keyStoreEntry = KeyStoreUtils.readToKeyStoreEntry();
// 生成cer证书
generateCert(keyStoreEntry, "d://server.g.cer");
// 读取cer证书
Certificate certificate = readCert("d://server.g.cer");
printInfo((X509Certificate) certificate);
}
}