我有一个第三方应用程序(我们不想使用),它可以从我们的读卡器中提取带有私钥的证书,并将其插入存储。正如我所说,我们不想使用它有很多原因,所以我们尝试通过PKCS11直接读取读卡器。在C#中开发时,我们使用PKCS11互操作库来管理它。但是,我无法检索链接到此证书的关联私钥。我该怎么做呢?
这是我的密码:
List<ObjectAttribute> objectAttributes = new List<ObjectAttribute>();
objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_CERTIFICATE));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, false));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
//objectAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, UTF8Encoding.UTF8.GetBytes("Certificat d'Authentification CPS")));
//CurrentSession.FindObjectsInit(objectAttributes);
oObjCollection = CurrentSession.FindAllObjects(objectAttributes);
//if (oObjCollection.Count > 0)
foreach (var item in oObjCollection)
{
var oAttriVal = CurrentSession.GetAttributeValue(item, new List<CKA>() { CKA.CKA_VALUE, CKA.CKA_ID }).FirstOrDefault();
oResult = new X509Certificate2(oAttriVal.GetValueAsByteArray());
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);
store.Add(oResult);
store.Close();
}如果我试图检索私钥,我可以,但它是不可读的,否则我看不出如何将它与我检索的证书相关联?
List<ObjectAttribute> objectAttributes = new List<ObjectAttribute>();
objectAttributes = new List<ObjectAttribute>();
objectAttributes = new List<ObjectAttribute>();
objectAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
objectAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_RSA));
CurrentSession.FindObjectsInit(objectAttributes);
var oObjCollection = CurrentSession.FindObjects(1);
if (oObjCollection.Count > 0)
{
oPrivKeyObjectHandle = oObjCollection[0];
}
List<ObjectAttribute> privKeyAttributes = new List<ObjectAttribute>();
if (oPrivKeyObjectHandle != null)
{
List<CKA> privKeyAttrsToRead = new List<CKA>();
privKeyAttrsToRead.Add(CKA.CKA_LABEL);
privKeyAttrsToRead.Add(CKA.CKA_ID);
privKeyAttrsToRead.Add(CKA.CKA_VALUE);
privKeyAttrsToRead.Add(CKA.CKA_VALUE_BITS);
privKeyAttributes = CurrentSession.GetAttributeValue(oPrivKeyObjectHandle, privKeyAttrsToRead);
}
CurrentSession.FindObjectsFinal();谢谢你的帮助
发布于 2015-07-07 08:29:41
我终于成功了。
我的程序如下:我使用第三方软件来分析存放的证书的私钥。
当我这样做时,我从第三方DLL加载CspParameters,如下所示:
var oParams = new CspParameters(1, "ASIP Sante Cryptographic Provider");
oParams.Flags = CspProviderFlags.UseExistingKey;
oParams.KeyNumber = (int)KeyNumber.Signature;
oParams.KeyContainerName = System.Text.RegularExpressions.Regex.Replace(GetAttributeValue(item, CKA.CKA_SUBJECT).First().GetValueAsString(), @"[^\u0020-\u007E]", string.Empty);在我的具体案例中,KeyContainerName是只有ASCII字符的对象(它不是默认的场景)。
当我用这个CSP创建RSACryptoServiceProvider时,它工作得很好,而且我最终不能使用第三方应用程序。
请注意,ASIP密码提供程序是与第三方软件一起安装的提供程序,该软件附带一个针对Windows CSP的特定DLL。
这段代码可能与Mono,Linux/Mac不兼容.
发布于 2015-07-06 13:53:38
在大多数情况下,您不会-大多数PKCS#11设备不允许您从设备中提取私钥,这是有原因的。
您所指的“驱动程序”很可能不提取密钥,而是在系统需要执行此类操作时调用设备上的签名和解密函数来使用私钥。这是由许多供应商提供的CSP模块完成的。
您也需要这样做,也就是说,如果不编写您自己的CSP (加密服务提供商),您很可能无法使用CryptoAPI进行操作,后者将与第三方应用程序相同。
https://stackoverflow.com/questions/31240980
复制相似问题