为什么我无法使用 PKCS#11 验证签名?
Why can't I verify signature with PKCS#11?
考虑一下,我已经创建了 PKCS#7 消息:
ContentInfo contentInfo = new ContentInfo(someByteArrayToSign);
SignedCms signedCms = new SignedCms(contentInfo);
var certificateFromFile = new X509Certificate2("myCert.pfx");
var signer = new CmsSigner(certificateFromFile);
signer.DigestAlgorithm = new Oid("1.3.14.3.2.26");
signedCms.ComputeSignature(signer);
var myCmsMessage = signedCms.Encode();
SendBytesOverNetwork(myCmsMessage);
现在,我要非常签名。以下方案有效(使用 BounceCastle
和 PKCS11.Interop
):
var signedPayloadCms = new CmsSignedData(GetBytesFromNetwork());
var data = (byte[])signedPayloadCms.SignedContent.GetContent();
byte[] signature = null;
foreach (SignerInformation signer in signedPayloadCms.GetSignerInfos().GetSigners())
{
if (signature != null)
{
throw new NotSupportedException("Multiple signature");
}
signature = signer.GetSignature();
}
var algCkm = CKM.CKM_SHA1_RSA_PKCS;
var mechanism = new Mechanism(algCkm);
Session.Verify(mechanism, somePublicKey.Handle, data, signature, out var isValid)
//isValid == true
但是当我使用CKM_RSA_PKCS
并手动计算HASH时,出现了错误:
var algHash = CKM.CKM_SHA_1;
var dataHash = Session.Digest(new Mechanism(algHash), data);
var algCkm = CKM.CKM_RSA_PKCS;
var mechanism = new Mechanism(algCkm);
Session.Verify(mechanism, somePublicKey.Handle, dataHash, signature, out var isValid)
//isValid == false
我错过了什么?为什么手动计算的哈希值无效?
事实证明,哈希需要用 DigestInfo 结构包装。最简单的方法是添加前缀:(前缀仅对 SHA-1 哈希有效):
var dataHash = Session.Digest(new Mechanism(algHash), data);
dataHash = HexToByteArray("30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14")
.Concat(dataHash).ToArray();
var algCkm = CKM.CKM_RSA_PKCS
...
在 RF3447C 中找到:https://www.ietf.org/rfc/rfc3447.txt
如何自己创建DigestInfo
:C# - How to calculate ASN.1 DER encoding of a particular hash algorithm?
考虑一下,我已经创建了 PKCS#7 消息:
ContentInfo contentInfo = new ContentInfo(someByteArrayToSign);
SignedCms signedCms = new SignedCms(contentInfo);
var certificateFromFile = new X509Certificate2("myCert.pfx");
var signer = new CmsSigner(certificateFromFile);
signer.DigestAlgorithm = new Oid("1.3.14.3.2.26");
signedCms.ComputeSignature(signer);
var myCmsMessage = signedCms.Encode();
SendBytesOverNetwork(myCmsMessage);
现在,我要非常签名。以下方案有效(使用 BounceCastle
和 PKCS11.Interop
):
var signedPayloadCms = new CmsSignedData(GetBytesFromNetwork());
var data = (byte[])signedPayloadCms.SignedContent.GetContent();
byte[] signature = null;
foreach (SignerInformation signer in signedPayloadCms.GetSignerInfos().GetSigners())
{
if (signature != null)
{
throw new NotSupportedException("Multiple signature");
}
signature = signer.GetSignature();
}
var algCkm = CKM.CKM_SHA1_RSA_PKCS;
var mechanism = new Mechanism(algCkm);
Session.Verify(mechanism, somePublicKey.Handle, data, signature, out var isValid)
//isValid == true
但是当我使用CKM_RSA_PKCS
并手动计算HASH时,出现了错误:
var algHash = CKM.CKM_SHA_1;
var dataHash = Session.Digest(new Mechanism(algHash), data);
var algCkm = CKM.CKM_RSA_PKCS;
var mechanism = new Mechanism(algCkm);
Session.Verify(mechanism, somePublicKey.Handle, dataHash, signature, out var isValid)
//isValid == false
我错过了什么?为什么手动计算的哈希值无效?
事实证明,哈希需要用 DigestInfo 结构包装。最简单的方法是添加前缀:(前缀仅对 SHA-1 哈希有效):
var dataHash = Session.Digest(new Mechanism(algHash), data);
dataHash = HexToByteArray("30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14")
.Concat(dataHash).ToArray();
var algCkm = CKM.CKM_RSA_PKCS
...
在 RF3447C 中找到:https://www.ietf.org/rfc/rfc3447.txt
如何自己创建DigestInfo
:C# - How to calculate ASN.1 DER encoding of a particular hash algorithm?