java实现根据csr生成证书_手把手实现TLS/SSL双向认证(附Websocket实现代码)

b5554f5ed2fdc50168e5198e8df9fc96.png

由于项目需求需要使用Websocket并实现SSL双向认真,java开发server端,C、go、python开发三种不同的client端。由于人力、时间有限,而且只大体上了解TLS/SSL协议,在具体实现过程中,发现网上参考资料是不少,但是写的都不是很详细,并存在误导的情况,怕了不少坑。

写这篇文章主要目的是想和有同样需要的小伙伴们分享一下经验:

  • 时间充足的话,建议还是全面系统的了解一下SSL协议及相关编程语言的实现过程、方法;
  • 如果着急赶项目,可以参考按照本文进行操作即可。

废话少说,直接上干货。

一、PKI、CA、TLS/SSL、OpenSSL等概念及原理

此处不再赘述,搜索引擎自行走一趟。

二、基于OpenSSL生成自签名证书

1、明确X509证书标准的两种编码格式PEM和DER

  • PEM(Privacy Enhanced Mail):内容是Base64编码的ASCII码文件,通常用于证书颁发机构(Certificate Authorities,CA),扩展名可为.pem/.crt/.cer/.key。纯文本以"-----BEGIN XXX-----" 和 "-----END XXX-----"作开头和结尾。服务器认证证书,中级认证证书(可理解为公钥)和私钥都可以储存为PEM格式。Apache和类似的服务器使用PEM格式证书。
  • DER(Distinguished Encoding Rules):使用二进制,扩展名为.der,但也经常使用.cer用作扩展名,所有类型的认证证书和私钥都可以存储为DER格式。Java是其典型使用平台。

2、证书相关文件常用扩展名

  • CRT :多用于*NIX系统,多数使用PEM编码,DER编码也有使用;
  • CER :多用于Windows系统,多数使用DER编码,PEM编码也有使用;
  • KEY:通常用于存放公钥或者私钥,非X509证书,PEM/DER编码均有;
  • CSR(Certificate Signing Request):证书签名请求,不是证书,用于证书颁发机构申请签名证书,是一个公钥和附加信息,在生成CSR时,还会生成一个私钥;
  • PFX/P12(predecessor of PKCS#12):CRT和KEY存在一个PFX文件中,通常会有一个”提取密码“,用于提取证书内容,使用的DER编码;
  • JKS (Java Key Storage):Java的专利,与OpenSSL关系不大,使用专用工具keytool生成具,可将PFX转为JKS。

使用openssl自签名产生SSL证书过程如下图:

fd6ba8cee69741fee6065af1e1c640b6.png
使用openssl自签名产生SSL证书过程

OpenSSL执行过程:

//1、生成CA秘钥,过程中要输入密码,这里用123456

openssl genrsa -des3 -out ca.key 2048

//2、生成证书请求文件,过程中输入密码:123456

openssl req -new -out ca.csr -key ca.key -keyform PEM -subj "/C=CN/ST=省/L=城市/O=单位/OU=部门/CN=域名或ip"

//3、生成自签名 根证书,过程中输入密码:123456

openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt -CAcreateserial

//4、生成server端秘钥,过程中输入密码:123456

openssl genrsa -des3 -out server.key 2048    

//5、生成server证书请求文件,过程中输入密码:123456

openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=省/L=城市/O=单位/OU=部门/CN=域名或ip"

//6、生成自签名SSL证书,过程中输入密码:123456

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

//7、生成client证书,与生成server证书过程一样,重复4-6步

三、WebSocket基于TLS/SSL双向认证通信(Python示例)

网上有一些http和https的SSL双向认证示例,没有挨个尝试,可自行搜索引擎。这里写一个Websocket的示例,仅供分享。

  • Python环境:3.6.6
  • 依赖模块:websockets

这里引用了部分Websockets example中的示例代码,感谢!

server.py(server端代码)

#!/usr/bin/env python

client.py(client端代码)

#!/usr/bin/env python

import asyncio
import pathlib
import ssl
import websockets

//服务端声明SERVER_AUTH,并加载server端证书
ssl_context=ssl.create_default_context(ssl.Purpose.SERVER_AUTH,cafile="cert/server.crt")
ssl_context.check_hostname=False
//certfile和keyfile参数为,证书及文件的路径
ssl_context.load_cert_chain(certfile="cert/client.crt",keyfile="cert/client.key")
ssl_context.verify_mode=ssl.CERT_REQUIRED

async def hello():
    uri = "wss://localhost:1234"
    async with websockets.connect(
        uri, ssl=ssl_context
    ) as websocket:
        name = input("What's your name? ")

        await websocket.send(name)
        print(f"> {name}")

        greeting = await websocket.recv()
        print(f"< {greeting}")

asyncio.get_event_loop().run_until_complete(hello())

总结

本文简要介绍了TLS/SSL双向认证的过程,并给出了示例代码,仅供参考,欢迎交流。

以上内容虽然简单,但均为原创,转载、引用请务必著名出处、作者,谢谢!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值