Java 中如何实现动态生成证书,像 Go 那样。

2023-01-04 22:14:01 +08:00
 dzdh

比如 go

func main() {

	ln, _ := tls.Listen("tcp", ":433", &tls.Config{
		GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
			// 使用 info.ServerName 从 DB 或者临时生成
			cert := generateX509Certificate(info.ServerName)
			return cert, nil
		},
	})

	http.ServeTLS(ln, nil, "", "")

}

Java 有类似的机制吗。哪怕是并发请求,也可以控制只有一个请求触发生成证书,其他请求 hold 住,等证书一旦生成成功,所有请求立刻进行接下来的握手(超时的不算)

Java 中不同的框架处理方式一样吗?

比如 javax.net.ssl.SSLContext 和使用 netty 的 spring 全家桶都适用的方法?

2130 次点击
所在节点    Java
14 条回复
jeesk
2023-01-04 22:55:16 +08:00
gomobile ,jni . 当然你可以自己用 java 重写。
jeesk
2023-01-04 22:57:11 +08:00
mkcert 项目,直接编译指定的平台就行了,如果是 java 自己直接使用 jni ,android,ios 都能用 gomobile.
passer9527
2023-01-04 23:27:26 +08:00
有,我做过
pierswu
2023-01-05 10:10:39 +08:00
你是想做证书续签吗?

java 项目可以不用管 ssl 证书的事情,交由 nginx 去配置 ssl 。
在使用 Certbot 或同类型的工具做证书自动续签,甚至可以自己写脚本去做续签或者生成新的证书
dzdh
2023-01-05 10:21:14 +08:00
@pierswu

场景是网关。可以 [随时] 新增、移除域名绑定。api.corp.com / openapi.corp.cn / api2.internal.corp.com 等等。根据当前域名去 pki 中心拿证书返回给客户端。go 实现这个很简单。java 咋搞捏。
dzdh
2023-01-05 10:23:03 +08:00
@pierswu

甚至还有些域名可能是需要通过自己做 ca 验证客户端证书。
dzdh
2023-01-05 10:24:23 +08:00
@dzdh #6 网关后台有个开关,点击开,立刻所有该域名后续的 tls 握手就必须是能要求强制客户端证书验证。点击关,就立刻该域名后续的所有 tls 握手时必须不验证客户端证书。
cnhongwei
2023-01-05 14:45:04 +08:00
1. JAVA 生成证书是没有问题的,就算 JCE 不行,bouncycastle 第三方包也可以,但感觉你的需求是 web 服务器能动态的更新客户端验证证书。这个感觉比较麻烦,现在就 Tomcat 和 netty 等服务器,你可以看看有没有 API 去动态更新证书的。
2. 你的需求比较奇怪,因为客户端去服务器拿到证书,再和服务器使用新证书,这个过程没有任何安全性,和客户端发 token ,再验证 token 没有什么区别。
3. 还有一种办法是用 nginx 处理 ssl,修改 nginx 的 ssl 配置,再重新加载 nginx 就行了。
pierswu
2023-01-05 16:41:35 +08:00
你可以参考这个文章试试
https://www.jianshu.com/p/62304d71c6bf
https://www.jianshu.com/p/642c0670c0bf
不同的 web 容器,方法是不一样的

我同意 8 楼的第三条,建议还是用 nginx 去管理 ssl ,需要动证书的时候重新加载 nginx 就行了。
dzdh
2023-01-05 21:45:31 +08:00
@cnhongwei #8
@pierswu #9

在不引入第三方组件( nginx 类)的情况下。纯 java 做不到吗?假设。我现在做一个 CDN 服务器,每个终端节点不就是要从中央仓库拿证书吗?再比如如果是 SM2 国密证书的场景,我需要判断客户端支持 SM 算法我就在本次握手时返回 SM 证书,否则返回 RSA 证书给客户端进行后续的握手操作。

像 Go 就只需要一个 tls 的 GetCertificate 就可以了。java 实现不了吗?

最近刚开始接触 java 。所以有点迷惑。我理解的这些语言不是都会把整个网络协议中的每一步操作都会封装成接口暴露出接口么。
pierswu
2023-01-06 10:18:58 +08:00
我明白你的意思了,但是我没接触过这种需求。
如果你使用的是 spring boot 框架的话,可以试着从 org.springframework.boot.web.server.SslStoreProvider 这个接口入手。
cnhongwei
2023-01-06 12:04:55 +08:00
如果 cdn 的话,理论上 SNI 过程的时候,你可以自动去获取并返回动态证书。netty 中有 SniHandler,我感觉从这里扩展是可以实现的。tomcat 8.5 以上支持 SNI ,但感觉扩展没有 netty 那么方便。
dzdh
2023-01-06 15:14:40 +08:00
@pierswu #11
@cnhongwei #12

佬们是通过什么渠道或方法知道有这个东西的呢?换句话说,就是咋学的呢?
cnhongwei
2023-01-06 15:17:17 +08:00
google

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/906619

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX