如何检测证书类型(A1或A3)?

Nic*_*rin 5 c# certificate .net-4.0 x509certificate2

我的机器上有两种类型的证书,一种是A1,另一种是A3,当将其中一种加载到一个X509Certificate2对象中时,如何以编程方式检测它是A1还是A3?

我知道如果没有插入A3证书,则无法访问私钥.考虑到两个证书都有效/已安装并已插入.

编辑

我刚刚发现了这些类型A1并且A3是由特定的国家立法(巴西)定义的,所以让我解释一下有什么区别:

ICP-Brasil允许8种类型的数字证书,分为2个系列(A和S).

A系列(A1,A2,A3和4)由数字签名证书组成,用于Web身份验证,电子邮件,虚拟专用网络(VPN)和电子文档,并验证其信息的完整性.
S系列(S1,S2,S3和S4)包括机密性证书,用于编码文件,数据库,消息和其他机密电子信息.这八种类型根据使用,安全级别和有效性进行区分.
(Gisele Ribeiro,来源)

证书类型

因此,为了更新我的问题,我希望检测证书是否来自具有密钥生成功能的智能卡.

bar*_*njs 8

据推测,你的A1和A3命名法是关于巴西标准(e-CPF/e-CNPJ /类似的东西).据我所知,这些术语意味着:

  • A1:软件私钥
  • A3:硬件私钥

(我真的很好奇A2是什么,但我离题了).

从技术上讲,证书不知道他们的密钥在哪里.因此,证书不知道其私钥(无论在哪里)是基于硬件还是软件.但是,根据http://www.bcb.gov.br/sfn/ced/ManualdeSeguran%C7adaRSFN-v32.pdfhttp://oid-info.com/get/2.16.76.1.2,它看起来像你可以做的事情:

private static bool IsBrazilA1Certificate(X509Certificate2 cert)
{
    // End with the "." so it matches on children, but not that OID.
    return HasParentEku(cert, "2.16.76.1.2.1.");
}

private static bool IsBrazilA3Certificate(X509Certificate2 cert)
{
    // End with the "." so it matches on children, but not that OID.
    return HasParentEku(cert, "2.16.76.1.2.3.");
}

private static bool HasParentEku(X509Certificate2 cert, string oidFragment)
{
    var ekuExtension = (X509EnhancedKeyUsageExtension) cert.Extensions["2.5.29.37"];

    if (ekuExtension == null)
    {
        return false;
    }

    foreach (Oid eku in ekuExtension.EnhancedKeyUsages)
    {
        if (eku.Value.StartsWith(oidFragment))
        {
            return true;
        }
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)

由于我没有巴西A1或A3证书,我无法真正测试这个,但这是我能从描述中得到的最好的.否则你会问"这有私钥吗?" (cert.HasPrivateKey)和"是硬件支持的私钥?" (一个更难的问题).

编辑:上述代码不遵循EKU验证的正常规则是没有价值的.通常,根本没有EKU扩展名的证书被视为具有所有EKU.但是,由于您正在明确查看根据巴西A1或A3政策创建的内容,因此它与您请求的内容相匹配.(此外,这是我见过的唯一一次必须使用基于StartsWith的规则进行验证,通常策略是特定的EKU OID)