无法将智能卡证书添加到 Yubikey

Posted

技术标签:

【中文标题】无法将智能卡证书添加到 Yubikey【英文标题】:Cannot add Smart Card Certificate to Yubikey 【发布时间】:2019-05-22 20:54:55 【问题描述】:

我正在尝试创建智能卡证书并将其添加回 Yubikey(我使用的是 Yubico 的 Mini 驱动程序,因此 yubikey 的行为类似于智能卡,不能使用它们的 PIVManager 或 YKMan)。我可以使用以下代码使用 yubikey 成功签署 CSR:

certificateRequest.CertRequest = new CX509CertificateRequestPkcs10();
certificateRequest.CertRequest.Initialize(X509CertificateEnrollmentContext.ContextUser);
certificateRequest.CertRequest.PrivateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_NONE;
certificateRequest.CertRequest.PrivateKey.Length = 2048;
certificateRequest.CertRequest.PrivateKey.ProviderName = "Microsoft Smart Card Key Storage Provider";
certificateRequest.CertRequest.PrivateKey.KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_SIGNING_FLAG;
certificateRequest.CertRequest.PrivateKey.KeySpec = X509KeySpec.XCN_AT_NONE;
certificateRequest.CertRequest.PrivateKey.MachineContext = false;
var subjectEncoded = new CX500DistinguishedNameClass();
subjectEncoded.Encode(certificateRequest.SubjectName);
certificateRequest.CertRequest.Subject = subjectEncoded;
certificateRequest.CertRequest.Encode();
certificateRequest.CSR = certificateRequest.CertRequest.RawData[EncodingType.XCN_CRYPT_STRING_BASE64REQUESTHEADER];

然后我去 CA 取回证书。当我尝试将证书添加回 Yubikey 时,出现以下错误:

CertEnroll::CX509Enrollment::InstallResponse: 找不到对象或属性。 0x80092004 (-2146885628 CRYPT_E_NOT_FOUND)

根据我在 google 上的发现,这意味着系统找不到签署证书的私钥。我正在使用请求来初始化容器,它仍然无法发现它是由智能卡完成的,这里是参考代码:

CX509Enrollment objEnroll = new CX509EnrollmentClass();
objEnroll.InitializeFromRequest(certificateRequest.CertRequest);
objEnroll.InstallResponse(
    InstallResponseRestrictionFlags.AllowUntrustedRoot,
    certificateRequest.StringCert,
    EncodingType.XCN_CRYPT_STRING_BASE64,
    null
);

有没有办法告诉 windows 在 YubiKey 中寻找私钥?

【问题讨论】:

【参考方案1】:

我错过了私钥的实际创建,这里的请求是新的完整代码:

certificateRequest.CertRequest = new CX509CertificateRequestPkcs10();
certificateRequest.CertRequest.Initialize(X509CertificateEnrollmentContext.ContextUser);
certificateRequest.CertRequest.PrivateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_NONE;
certificateRequest.CertRequest.PrivateKey.Length = 2048;
certificateRequest.CertRequest.PrivateKey.ProviderName = "Microsoft Smart Card Key Storage Provider";
certificateRequest.CertRequest.PrivateKey.KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_SIGNING_FLAG;
certificateRequest.CertRequest.PrivateKey.KeySpec = X509KeySpec.XCN_AT_NONE;
certificateRequest.CertRequest.PrivateKey.MachineContext = false;
certificateRequest.CertRequest.PrivateKey.Create();
var subjectEncoded = new CX500DistinguishedNameClass();
subjectEncoded.Encode(certificateRequest.SubjectName);
certificateRequest.CertRequest.Subject = subjectEncoded;
certificateRequest.CertRequest.Encode();
certificateRequest.CSR = certificateRequest.CertRequest.RawData[EncodingType.XCN_CRYPT_STRING_BASE64REQUESTHEADER];

然后我去 CA 取回证书。当我尝试将证书添加回 Yubikey 时:

CX509Enrollment objEnroll = new CX509EnrollmentClass();
objEnroll.InitializeFromRequest(certificateRequest.CertRequest);
objEnroll.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64);
objEnroll.InstallResponse(
    InstallResponseRestrictionFlags.AllowUntrustedRoot,
    certificateRequest.StringCert,
    EncodingType.XCN_CRYPT_STRING_BASE64,
    null
);

【讨论】:

以上是关于无法将智能卡证书添加到 Yubikey的主要内容,如果未能解决你的问题,请参考以下文章

使用客户端证书的智能卡身份验证

将证书从智能卡复制到计算机

读取智能卡上的证书

使用 C# 从 PKI 智能卡读取证书

基于证书的登录

使用 smartcardio 签署文件