【分享】自签名证书 和 SpringBoot单双向认证配置及测试

举报
Lily_w 发表于 2021/07/28 14:04:39 2021/07/28
【摘要】 由于经常用到,所以分享(记录)一下:)这里主要使用openssl命令,因为用keytool使用生成的证书格式比较少,还不能直接用命令行进行私钥证书解密。如果大家没有linux机子,也可以在windows环境下安装openssl(安装方法自行搜索哦~)生成CA证书密钥长度2048,过期时间365天,最后面的-subj参数各=后面分别是国家、省(州)、市、组织和common name,所有的参数...

由于经常用到,所以分享(记录)一下:)

这里主要使用openssl命令,因为用keytool使用生成的证书格式比较少,且不能直接用命令行进行私钥证书解密。

如果大家没有linux机子,也可以在windows环境下安装openssl(安装方法自行搜索哦~)

生成CA证书

密钥长度2048,过期时间365天,最后面的-subj参数各=后面分别是国家、省(州)、市、组织和common name,所有的参数请根据自己的需要进行修改,安全级别要求高的,请将密钥长设置为3072
openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout ca.key -out ca.crt -subj "/C=CN/ST=GD/L=SZ/O=HW/CN=HW"

生成服务端和客户端证书

1.先生成私钥:

openssl genrsa -out server.key 2048

2.生成证书请求文件,这一步的CN=后面的127.0.0.1要修改为自己的服务端(即使用者)地址(IP或域名):

openssl req -new -sha256 -out server.csr -key server.key -subj "/C=CN/ST=GD/L=SZ/O=HW/OU=RDC/CN=127.0.0.1"

3.添加扩展信息(可选),这一步骤如果是在windows上直接自己创建一个cert_extensions文本文件,里面的内容为subjectAltName=DNS:www.test.com,IP:192.168.1.2,这里是设置使用者可选名称,可以设置多个,用逗号相隔开即可。如果是在linux上,则使用下面的命令:

echo "subjectAltName=DNS:www.test.com,IP:192.168.1.2,IP:192.168.1.3" > cert_extensions

4.用ca证书进行签发,后面的-extfile cert_extensions是扩展信息可选的

openssl x509 -req -days 365 -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt -extfile cert_extensions

使用同样的方法生成客户端证书

本质上讲客户端证书和服务端证书是一样的,我们把服务端使用的证书叫服务端证书,客户端使用的证书叫客户端证书

证书格式转化

我们现在有了ca证书、ca签名的服务端和客户端证书(都有公私钥),但实际使用时不同的语言或不同的部署方法可能需要不同格式的证书,需要根据不同的情况进行格式转化。

1、将服务端、客户端证书转为p12格式,p12格式的证书包含公私钥,这时候会让我们设置p12证书的密码,要记住密码

openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12 -name "server"
openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -name "client"

2、服务端证书转为jks格式,这里用到keytool,会要求输入p12证书的密码,同时设置jks证书密码

keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 -deststoretype JKS -destkeystore server.jks

把ca证书(指ca公钥ca私钥请自行保存,不能给服务端或客户端)导入server.jks,如果服务端有单独的信任链证书,也可以导入另外的信任链证书中,这里我测试的时候直接用的server.jks,其中123456是server.jks证书密码
keytool -importcert -alias ca -keystore server.jks -storepass 123456 -file ca.crt

3、把client证书转为pem格式

openssl pkcs12 -clcerts -out clientWithKey.pem -in client.p12

上一步生成的clientWithKey.pem中的私钥是加密的,如果要使用不加密的私钥,则需要解密,其中123456是生成client.p12证书的密码

openssl pkey -in clientWithKey.pem -outform pem -out clientKeyPem.pem -passin pass:123456

最后把clientWithKey.pem中的公钥和解密后的私钥clientKeyPem.pem内容放到同一个文件中,得到client.pem(可自定义命名):

这样我们就完成了证书的准备。

SpringBoot服务端配置

原来默认使用http,如果使用https,接口开发都不变,只是添加一些配置即可:

1.启动配置

在启动入口(即main)添加:

@Bean
public TomcatServletWebServerFactory servletContainer() {
    TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
        @Override
        protected void postProcessContext(Context context) {
            SecurityConstraint constraint = new SecurityConstraint();
            constraint.setUserConstraint("CONFIDENTIAL");
            SecurityCollection collection = new SecurityCollection();
            collection.addPattern("/*");
            constraint.addCollection(collection);
            context.addConstraint(constraint);
        }
    };
    tomcat.addAdditionalTomcatConnectors(httpConnector());
    return tomcat;
}

@Bean
public Connector httpConnector() {
    Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
    connector.setScheme("http");
    //Connector监听的http的端口号
    connector.setPort(8080);
    connector.setSecure(false);
    //监听到http的端口号后转向到的https的端口号
    connector.setRedirectPort(443);
    return connector;
}

2.添加application配置(以下配置是yaml格式):

单向认证

server:
  port: 443
  ssl:
    key-store: src/main/resources/server.jks
    key-store-password: 123456
    key-store-type: JKS

双向认证:这里的trust-stores一般会设置单独的信任链证书,这里测试时我直接使用server.jks,见证书格式转化时的说明

server:
  port: 443
  ssl:
    key-store: src/main/resources/server.jks
    key-store-password: 123456
    key-store-type: JKS
    # 双向认证
    client-auth: need
    trust-store: src/main/resources/server.jks
    trust-store-password: 123456

如果把client-auth的值设置为none就是单向认证,单向认证时不需要设置truest-store,设置为need就是双向认证,设置为want则两种方式都支持

测试:

单向认证:curl https://10.25.123.220:443/xxx -X GET -v -k

双向认证:curl https://10.25.123.220:443/xxx -X GET -v --cacert ./ca.crt --cert ./client.pem,这里用的client.pem里面有客户端公私钥

最后补充一下keytool自签名证书方法:

用相同的方法生成ca/server/client的keypair(放在各自的keystore文件中):
keytool -genkeypair -alias ca -keystore d:\certTest\ca.keystore -storepass 123456
查看内容:
keytool -list -keystore d:\certTest\client.keystore -storepass 123456 -v
生成证书请求文件:
keytool -certreq -alias client -keystore d:\certTest\client.keystore -storepass 123456 -file d:\certTest\client.csr
用ca进行证书签发:
keytool -gencert -alias ca -keystore d:\certTest\ca.keystore -storepass 123456 -infile d:\certTest\client.csr -outfile d:\certTest\client.cer    
导出ca证书(包含ca公钥),如果有需要可以用此方法导出其他证书,这里我们只导出ca证书
keytool -exportcert -alias ca -keystore d:\certTest\ca.keystore -storepass 123456 -file d:\certTest\ca.cer

把ca证书和ca签名的client证书都导入到client的keystore中,导入的client.cer将会替换原来client.keystore中相同别名的证书
keytool -importcert -alias ca -keystore d:\certTest\client.keystore -storepass 123456 -file d:\certTest\ca.cer
keytool -importcert -alias client -keystore d:\certTest\client.keystore -storepass 123456 -file d:\certTest\client.cer

转为jks格式
keytool -importkeystore -srckeystore d:\certTest\client.keystore -destkeystore d:\certTest\client1.jks -deststoretype JKS

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。