概述
为了接入SSL,故了解证书的种类/结构/生成方式和使用方式。
证书的结构
证书包含签发方信息,拥有者信息,公钥,签名等。
签名是使用签发方私钥对证书进行加密运算的来,通过使用签发方公钥解密可以验证证书真伪。
证书格式参考:https://blog.csdn.net/jjxojm/article/details/81266601
证书的种类
先了解两种证书,一种是自签证书,另一种是由机构签发的证书。
- 自签证书,也就是颁发者是自己,使用自己的私钥来对证书的信息进行签名。我认为根证书就是自签证书,客户端一般自带根证书,并且信任根证书签发的任何证书。
- 机构颁发证书,就是通过机构来签发的,可能是根级机构也可能是二级机构,使用机构的私钥来对证书的信息进行签名。
证书的生成
我们可以通过openssl或者jdk提供的keytool来生成证书以及证书对应的私钥。
-
openssl的相关配置及数据
(1)配置文件 /etc/pki/tls/openssl.cnf
生成的证书会根据配置文件生成。
由于ca包含CA_default包含usr_cert,在生成用户证书时会将usr_cert的参数生成到证书中。而chrome需要校验使用者备用名称,所以需要在usr_cert中增加subjectAltName = @altNames
再增加以下配置
[ alt_names ]
DNS.1 = localhost # 此处是用户的域名
参考链接:https://my.oschina.net/jsan/blog/643653
(2)证书索引 /etc/pki/CA/index.txt
第一次使用openssl时需要手动创建此文件,如果想重新生成同一个证书,也需要在此删除旧的证书记录
(3)证书序号 /etc/pki/CA/serial
记录当前证书序号,保证每次生成的序号唯一,需要初始化为00 -
openssl-生成自签证书
(1)先生成私钥,如下语句会生成RSA私钥
openssl genrsa -out root.key 1024
(2)使用私钥生成自签证书
openssl req -new -x509 -key root.key -out root.crt -
openssl-生成二级机构证书
(1)生成私钥
openssl genrsa -out second.key 1024
(2)生成证书请求
openssl req -new -key second.key -out second.csr
注意:国家信息与organization信息需要与根证书一致
(3)使用根证书签名,生成证书
openssl ca -extensions v3_ca -in second.csr -out second.crt -cert root.crt -keyfile root.key
此处的-extensions v3_ca会将basicConstraints改为CA:true,才允许签发证书。 -
openssl-生成机构颁发证书
(1)生成私钥
openssl genrsa -out mywebsite.key 1024
(2)生成证书请求
openssl req -new -key mywebsite.key -out mywebsite.csr
注意国家信息与organization信息需要与根证书一致
(3)使用二级机构证书签名,生成证书
openssl ca -in mywebsite.csr -out mywebsite.crt -cert second.crt -keyfile second.key
上面遇到了key/crt/csr这几种格式,key一般指私钥,crt是证书(不含私钥),csr是证书生成请求,需要机构签发生成crt。
-
openssl-合成证书链
由于一个证书依赖上一级证书进行验证,所以服务器需要提供整个证书链给客户端进行校验。合成证书链只需要将文件按序合并即可。
cat root.crt second.crt mywebsite.crt > chain.crt -
证书转换
java中需要使用keystore进行ssl,如果是openssl的证书需要转化成jks
(1)先将网站私钥和证书链合成pfx文件
openssl pkcs12 -export -out chain.pfx -inkey mywebsite.key -in chain.crt
(2)将pfx转化成jks
keytool -importkeystore -srckeystore chain.pfx -destkeystore chain.jks -srcstoretype PKCS12 -deststoretype JKS -
keytool-生成自签证书
keytool -genkey -alias mykey -keyalg RSA -keypass mypass -keystore mystore -storepass mystorepass
这个语句可直接生成keystore,keystore相当于key和crt的集合
Netty接入SSL
- 使用JDK的SSLContext
参考链接:https://blog.csdn.net/huangshanchun/article/details/78305964
(1)获取SSLContext
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream in = new FileInputStream("chain.jks");
ks.load(in, "keystorepass".toCharArray());
in.close();
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, "keypass".toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLSv1");
sslContext.init(kmf.getKeyManagers(), null, null);
(2)pipeline中加入SslHandler
SSLEngine engine = getSSLContext().createSSLEngine();
engine.setUseClientMode(false);//不校验客户端证书
ch.pipeline().addLast(new SslHandler(engine));
- 使用Netty的SslContext
(1)获取SSLContext
public static SslContext getSslContext() throws Exception {
File certChainFile = new File("openssl\chain.crt");
File keyFile = new File("openssl\mywebsite.pkcs8");
File rootFile = new File("openssl\root.crt");
SslContext sslCtx = SslContextBuilder.forServer(certChainFile, keyFile).trustManager(rootFile).protocols("TLSv1.2").clientAuth(ClientAuth.NONE).build();
return sslCtx;
}
此处的keyFile是pkcs8格式,直接使用pem格式会报错,可以通过如下命令转换
openssl pkcs8 -topk8 -in mywebsite.key -out mywebsite.pkcs8 -nocrypt
(2)pipeline中加入SslHandler
ch.pipeline().addLast(SSLContextFactory.getSslContext().newHandler(ch.alloc()));
最后
以上就是热情春天为你收集整理的SSL证书生成与使用(基于Netty)的全部内容,希望文章能够帮你解决SSL证书生成与使用(基于Netty)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复