C# 验证未分离的PKCS签名
亲爱的 请帮助我了解非分离签名验证过程。 我使用了从和CheckSignature文档中稍微修改的示例代码。 给你C# 验证未分离的PKCS签名,c#,.net,cryptography,C#,.net,Cryptography,亲爱的 请帮助我了解非分离签名验证过程。 我使用了从和CheckSignature文档中稍微修改的示例代码。 给你 [TestMethod] public void CheckSignaturePlain() { var x509 = new X509Helper(LogManager.GetLogger("x509")); X509Certificate2 certificate = x509.GetCertificate("XML_SIGN_TEST_CERT");
[TestMethod]
public void CheckSignaturePlain()
{
var x509 = new X509Helper(LogManager.GetLogger("x509"));
X509Certificate2 certificate = x509.GetCertificate("XML_SIGN_TEST_CERT");
var str = "quick brown fox jumps over lazy dog";
var data = Encoding.ASCII.GetBytes(str);
detached = false; // tests are passed for detached signatures only
using (var sha256 = new SHA256CryptoServiceProvider()) // One thing though, Microsoft recommends that you avoid using any managed classes. You should change SHA256Managed to SHA256CryptoServiceProvider. https://blogs.msdn.microsoft.com/winsdk/2015/11/14/using-sha256-with-the-signedxml-class/
{
var hash = sha256.ComputeHash(data);
var signature = Sign(hash, certificate);
SignCheck(hash, signature);
try
{
data = data.Skip(1).ToArray(); // lets change the data to get broken signature
var hash2 = sha256.ComputeHash(data);
SignCheck(hash2, signature);
Assert.Fail("signature verification should fail");
}
catch (CryptographicException ce)
{
TestContext.WriteLine(ce.Message);
}
}
}
byte[] Sign(byte[] hash, X509Certificate2 cert)
{
ContentInfo contentInfo = new ContentInfo(hash);
SignedCms signedCms = new SignedCms(contentInfo, detached);
CmsSigner cmsSigner = new CmsSigner(cert);
cmsSigner.IncludeOption = X509IncludeOption.WholeChain;
signedCms.ComputeSignature(cmsSigner);
byte[] cmsMessage = signedCms.Encode();
return cmsMessage;
}
bool detached;
void SignCheck(byte[] hash, byte[] signature)
{
var contentInfo2 = new ContentInfo(hash);
var signedCms = new SignedCms(contentInfo2, detached);
signedCms.Decode(signature);
signedCms.CheckSignature(true);
}
然而,从我的观点来看,它只适用于分离的签名。
如果设置了detached=false,则更改数据的签名验证不会失败。
之所以会发生这种情况,是因为签名的数据包含在signature对象中,并且SignedCms.CheckSignature忽略根据更改的数据计算的哈希值
是否可以使用非分离签名并获取signedCms.CheckSignature以考虑从更改的数据计算的哈希?
或者我应该从未分离的签名中提取签名数据,计算数据的散列并手动比较它们
我想用非分离签名。签名散列中的签名数据实际上应该用作抽象层上的消息标识符,抽象层不知道如何计算不同类型对象的散列。在非分离模式下,内容在有效负载内,因此,在解码过程中,您提供的ContentInfo将被丢弃,取而代之的是有效负载中的ContentInfo
if (!this.Detached) {
Oid contentType = PkcsUtils.GetContentType(m_safeCryptMsgHandle);
byte[] content = PkcsUtils.GetContent(m_safeCryptMsgHandle);
m_contentInfo = new ContentInfo(contentType, content);
}
从
在分离签名模式下,SignedCms数据表示必须提供的某些数据上的签名和元数据。使用标准的加密签名行为,它获取输入数据,对其进行散列,并对散列执行私钥操作以生成签名
在嵌入式非分离签名模式下,SignedCms数据是一个包含数据以及签名和元数据的单个blob。因此,以非分离模式发送CMS对象取代了发送原始数据,因为原始数据现在已嵌入
除非您想要传输的东西实际上只是散列,否则您应该向SignedCms提供实际的数据值,因为它将散列数据本身作为计算签名的一部分。谢谢您确认了我的想法。让我们把这当作一个答案