On Friday, November 27, 2015 at 2:25:52 PM UTC+8, agentzh wrote:
Hello!
2015-11-27 13:30 GMT+08:00 <paul...@gmail.com>:
> 你好,最近用你的lua-nginx-module-ssl-cert-by-lua分支有一些疑问,想向你请教下:
> 1.
> 分支不支持pem格式的证书,我看了下源码主要是lua-nginx-module-ssl-cert-by-lua/src/ngx_http_lua_sslcertby.c中的函数ngx_http_lua_ffi_ssl_set_der_certificate
>
> 函数在解析证书文件时,你用的openssl接口是d2i_X509_bio;其实若传进来的数据是文本PEM格式的,可以用PEM_read_bio_X509_AUX接口直接解析返回x509
> 证书结构。当时你实现的时候没考虑用这个接口是否是因为lua传二进制缓存更加安全?还是其他?
目前的接口当时选择使用 DER 主要是为了直接缓存 DER 而非 PEM. DER 比 PEM
更紧凑更小巧,同时解析起来也更快。不过从现在看来,直接缓存 OpenSSL 解析后的二进制数据结构要比 DER 还要更加高效,毕竟解析
DER 还会在 OpenSSL 内部发生昂贵的 malloc 等动态内存分配操作。确实,这里的 API 最好重新设计一下,以 PEM
作为原始输入,以 OpenSSL 解析证书链后生成的 cdata 作为设置证书链的 API 所使用的输入(这里的 cdata 可以通过
lua-resty-lrucache 进行缓存)。当时使用 DER 而没什么安全上的考量,毕竟证书都是公开的信息。
恩,明白你的意思 。对于你说的 「cdata 可以通过 lua-resty-lrucache 进行缓存」,我下去研究下,这块不懂:)
> 2.
> der编码的证书有个缺点,就是只能对单个证书,不能是证书链(我目前在网上搜索的资料,存证书链都是用pem格式的,很少用der编码的),而PEM格式的证书
> 可以是证书链。所以,在你的实现中,虽然有对der编码证书循环读证书链,但是der编码证书文件中只有一个证书,故中间证书缺失,导致ssl握手证书验证不过。
是的,这是一个常见的潜在问题。如果用户使用外部工具链自己进行 pem -> der 的(预)转换,很可能导致证书链不完整。目前的 API
需要用户自己调用 ngx.ssl 模块中的 cert_pem_to_der() 函数进行 PEM 到 DER 的转换。这个 API
会保留完整的证书链。
恩,看到你实现了这个转换的函数,不过还没测试过,我得先测试下 :)
> 3. 目前https服务证书格式基本上都是pem的,很少有der编码的,故个人觉得将此接口改为pem的较好;
目前的 Lua API 其实也只是把 DER 作为中间编码。当然,我觉得直接用 OpenSSL 生成的 C 数据结构的指针作为中间结果更高效也更灵活。
恩,确实是这样的
> 4. 当然,私钥也可改变为pem格式的证书;
>
私钥使用 DER 的好处是方便直接进行上一层的加密。当然,我们可以提供 priv_key_pem_to_der()
这个转换函数(我记得已经有 pull request 实现了该函数)。
恩,明白,一般cert和prikey方法都是成对的,你应该提供了:)
Regards,
-agentzh