You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elixir实现PKI证书链验证遇无效颁发者错误求助

解决Elixir中PKI证书链验证的{:bad_cert, :invalid_issuer}错误

问题根源分析

你的代码出现invalid_issuer错误,主要是三个核心问题导致:

  1. 参数传递逻辑错误::public_key.pkix_path_validation/3的第二个参数仅接受信任锚(根CA),而非完整证书链;中间CA、签名CA需要放在选项的:untrusted_chain中,对应openssl命令的-untrusted参数。
  2. 证书格式不匹配:使用X509.Certificate.from_pem/1得到的是X509库结构体,而:public_key模块需要OTP原生的DER二进制证书格式。
  3. 路径长度限制不合理:设置{: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 23:06:24