颁发机构获得签名证书的申请,其核心内容是一个公钥(当然还附带了一些别的信息),在生成这个申请的时候,同时也会生成一个私钥,私钥要自己保管好。
查看的办法:openssl req -noout -text -in my.csr
PFX/P12 - predecessor of PKCS#12,对*nix服务器来说,一般CRT和KEY是分开存放在不同文件中的,但Windows的IIS则将它们存在一个PFX文件中,(因此这个文件包含了证书及私钥),PFX通常会有一个"提取密码",你想把里面的东西读取出来的话,它就要求你提供提取密码,PFX使用的时DER编码,如何把PFX转换为PEM编码?
openssl pkcs12 -in for-iis.pfx -out for-iis.pem -nodes
这个时候会提示你输入提取代码. for-iis.pem就是可读的文本.
生成pfx的命令类似这样:openssl pkcs12 -export -in certificate.crt -inkey privateKey.key -out certificate.pfx -certfile CACert.crt其中CACert.crt是CA(权威证书颁发机构)的根证书,有的话也通过-certfile参数一起带进去.这么看来,PFX其实是个证书密钥库.
JKS - 即Java Key Storage,这是Java的专利,跟OpenSSL关系不大,利用Java的一个叫"keytool"的工具,可以将PFX转为JKS
5.4 证书编码的转换
6. 自建证书
OpenSSL 是一个免费开源的库,它提供了构建数字证书的命令行工具。一般都是三级证书,为了简单我就只做2级了,大家可以自己签发三级。
6.1 创建 Root CA
a) 生成根证书私钥
$ openssl genrsa -aes256 -out cakey.pem 2048 (生成私钥)
$ openssl pkcs8 -topk8 -in cakey.pem -out ca.key -nocrypt (grpc格式)
b)生成根证书签发申请文件
$openssl req -new -key ca.key -out ca.csr -subj "/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=wwc" (/CN代表的就是域名)
c)自签发根证书(cer文件)
$ openssl x509 -req -days 365 -sha1 -extensions v3_ca -signkey ca.key -in ca.csr -out ca.cer
6.2 签发自建证书
a) 生成证书私钥
$ openssl genrsa -aes256 -out server.pem 2048 (生成私钥)
$ openssl pkcs8 -topk8 -in server.pem -out server.key -nocrypt
b)生成证书签发申请文件
$openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=wancai"
c)使用根证书签发服务端证书
$ openssl x509 -req -days 365 -sha1 -extensions v3_req -CA ca.cer -CAkey ca.key -CAserial ca.srl -CAcreateserial -in server.csr -out server.cer
7. gRPC使用自建证书
将server.cer(证书)和server.key(私钥)拷贝到工作目录
gRPC的通信组件是netty、okhttp,netty带了ssl实现,有动态和静态两种方式来提供TLS的实现库,为了开发方便,我这里使用了boringssl实现库。okhttp也实现了TLS,但okhttp使用在移动端,故在此不表。
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-all</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>1.1.33.Fork23</version>
</dependency>
gRPC Server端
使用TLS,添加证书和私钥
/* The port on which the server should run */
int port = 8443;
server = ServerBuilder.forPort(port)
.addService(new GreeterImpl())
.useTransportSecurity(loadCert("server.cer"),loadCert("server.key"))
.build()
.start();
logger.info("Server started, listening on " + port);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
// Use stderr here since the logger may have been reset by its JVM shutdown hook.
System.err.println("*** shutting down gRPC server since JVM is shutting down");
HelloWorldServer.this.stop();
System.err.println("*** server shut down");
}
});
gRPC Client端
添加信任的证书,同时注意刚才我们建立证书的时候,域名是wancai,所以在这里需要添加域名,否则链接失败。
SslContext sslContext = null;
try {
sslContext = Gr