Elixir实现PKI证书链验证遇无效颁发者错误求助
解决Elixir中PKI证书链验证的
{:bad_cert, :invalid_issuer}错误 问题根源分析
你的代码出现invalid_issuer错误,主要是三个核心问题导致:
- 参数传递逻辑错误:
:public_key.pkix_path_validation/3的第二个参数仅接受信任锚(根CA),而非完整证书链;中间CA、签名CA需要放在选项的:untrusted_chain中,对应openssl命令的-untrusted参数。 - 证书格式不匹配:使用
X509.Certificate.from_pem/1得到的是X509库结构体,而:public_key模块需要OTP原生的DER二进制证书格式。 - 路径长度限制不合理:设置
{:max_path_length, 0}会强制要求设备证书直接由根CA签名,与你包含中间CA、签名CA的链结构冲突。
修正后的代码实现
以下代码完全对齐openssl verify -CAfile certs/root_ca.pem -untrusted cert_chain.pem certs/device_cert.pem的验证逻辑:
defmodule Cert do def validate_device_cert do # 1. 读取并解析目标设备证书 device_cert_pem = File.read!("software_signing.pem") [{:Certificate, device_cert_der, _}] = :public_key.pem_decode(device_cert_pem) # 2. 读取并解析根CA作为信任锚(对应openssl的-CAfile) root_ca_pem = File.read!("root_ca.pem") [{:Certificate, root_ca_der, _}] = :public_key.pem_decode(root_ca_pem) trust_anchors = [root_ca_der] # 3. 读取并解析非信任中间链(对应openssl的-untrusted) intermediate_chain_pem = File.read!("cert_chain.pem") untrusted_chain = intermediate_chain_pem |> :public_key.pem_decode() |> Enum.map(fn {:Certificate, der, _} -> der end) # 4. 执行PKIX路径验证,调整max_path_length适配实际链结构 :public_key.pkix_path_validation(device_cert_der, trust_anchors, [ {:untrusted_chain, untrusted_chain}, {:max_path_length, 2} # 示例:若链为根CA→中间CA→签名CA→设备,此处设为2(中间CA层数) ]) end end
关键注意事项
- 证书链层级检查:先通过
openssl手动验证链有效性,确保设备证书的issuer与签名CA的subject一致,中间CA的issuer与根CA的subject一致。 - 路径长度调整:
:max_path_length值为允许的中间CA最大层数(不含根CA和目标证书),需根据你的实际链结构修改。 - 证书顺序:非信任链中的证书建议按「设备证书直接 issuer → 上层CA」的顺序排列,虽然验证逻辑不强制,但便于排查问题。
内容的提问来源于stack exchange,提问作者Umer Kiani
相关产品推荐
相关产品推荐

