OpenResty中如何读取客户端证书的Subject字段?
解决OpenResty解析客户端证书Subject字段的问题
问题根源
ngx.var.ssl_client_cert返回的证书内容是去除了换行符的PEM格式,而ngx.ssl.parse_pem_cert和resty.openssl.x509.new都要求标准的带换行的PEM格式(包括证书主体部分的换行),这就是你遇到解析错误的核心原因。
修复代码
先对获取到的证书字符串进行格式化,补全必要的换行,再进行解析。以下是可用的实现代码:
content_by_lua_block { local cjson = require "cjson" local x509 = require "resty.openssl.x509" -- 获取客户端证书 local cert_raw = ngx.var.ssl_client_cert if not cert_raw then ngx.say(cjson.encode({error = "no client certificate provided"})) return end -- 格式化证书:补全换行符,转换为标准PEM格式 local cert_formatted = cert_raw:gsub("-----BEGIN CERTIFICATE-----", "-----BEGIN CERTIFICATE-----\n") cert_formatted = cert_formatted:gsub("-----END CERTIFICATE-----", "\n-----END CERTIFICATE-----") -- 给证书主体部分每64字符添加换行(符合PEM规范) cert_formatted = cert_formatted:gsub("([^\n]{64})", "%1\n") -- 解析证书 local x509_cert, err = x509.new(cert_formatted, x509.FORMAT_PEM) if not x509_cert then ngx.log(ngx.ERR, "failed to parse certificate: ", err) ngx.say(cjson.encode({error = err})) return end -- 获取Subject字段 local subject = x509_cert:get_subject_name() -- 将Subject转换为可读字符串(或根据业务需求处理) local subject_str = tostring(subject) -- 输出结果 ngx.say(cjson.encode({ certificate_subject = subject_str, certificate_raw = cert_raw })) }
关键说明
- 必须确保你的Nginx配置已经开启客户端证书验证,相关配置示例:
server { listen 443 ssl; ssl_certificate /path/to/server.crt; ssl_certificate_key /path/to/server.key; # 开启客户端证书验证 ssl_client_certificate /path/to/ca.crt; ssl_verify_client on; ssl_verify_depth 2; } - 使用
resty.openssl.x509的get_subject_name()方法可以直接获取证书Subject,比手动解析更可靠,等效于openssl x509 -text -noout -in cert.pem中的Subject输出。
内容的提问来源于stack exchange,提问作者froy001
相关产品推荐
相关产品推荐

