Mik*_*ogi 5 c# cryptography digital-signature
我在我的方法中收到一个XML文档作为字符串参数.XML文档是:
<Document>
<ZipContainer> Zip_File_In_Base64 </ZipContainer>
<X509Certificate> Certificate_In_Base64 </X509Certificate>
</Document>
Run Code Online (Sandbox Code Playgroud)
从这个字符串中我提取了base64格式的ZIP文件和base64格式的X509Certificate2证书.ZIP文件包含:
将ZIP文件的内容描述为XML(文件packageDescription.xml)的文件;
包含传输文件内容的文件(例如*.doc文件);
具有分离数字签名内容的*.p7s文件(文件 - 分离的数字签名);
从归档应该提取签名的签名文件(分离的数字签名可能不止一个).分离的数字签名存储在具有.p7s扩展名的文件中.必须完成每个签名以检查其与数字签名的协议,用户使用该签名登录到门户.
必须包括两个步骤:
请参阅方法certificateValidator()(请参阅下面的此方法):这是一个分离的签名,包含在.p7s文件中,其中包含相应的签名文件,这些*.P7S-文件.
例如:一对相关文件:ZayavUL_3594c921f545406d9b8734bbe28bf894.doc_1.p7s和
ZayavUL_3594c921f545406d9b8734bbe28bf894.doc.
请参阅方法certificateValidator():此方法验证来自文件.p7s的证书,该证书具有从XML文档输入字符串中提取的证书.
该方法signatureValidator(请参阅下面的此方法)当前未使用文件的分离签名.p7s.我试过了,但没有成功.如何正确验证.p7s其相应文件的文件的分离签名?
在该方法中certificateValidator(请参阅下面的此方法),如何验证从.p7s文件中提取的证书与从Base64格式的输入字符串中提取的证书的一致性?
代码行foreach (X509Certificate2 x509 in signCms.Certificates) { }--->证书集合总是空的.为什么?
Dictionary <string, byte[]> dictP7SFiles (key - 文件名*.p7s,value - 字节数组,表示*.p7s文件)
Dictionary <string, byte[]> dictNotP7SFiles (key - 使用*.p7s文件中的分离签名签名的文件的名称,value - 字节数组,表示文件)
X509Certificate2 userCertX509 - 证书对象,从输入的xml文档中提取(其格式为Base64)
以下是测试验证步骤的实施(参见上面的这2个步骤):
private bool certificateValidator(Dictionary<string, byte[]> dictP7SFiles,
Dictionary<string, byte[]> dictNotP7SFiles, X509Certificate2 userCertX509)
{
bool isValid = false;
try
{
foreach (KeyValuePair<string, byte[]> pair in dictP7SFiles)
{
ContentInfo contentInfo = new ContentInfo(pair.Value);
SignedCms signCms = new SignedCms(contentInfo, true);
if (signCms.Certificates.Count != 0)
{
//Certificates Collection always is empty. Why?
foreach (X509Certificate2 x509 in signCms.Certificates)
{
if ((x509.SerialNumber != userCertX509.SerialNumber)
|| (x509.Thumbprint != userCertX509.Thumbprint))
{
isValid = false;
return isValid;
}
}
isValid = true;
return isValid;
}
}
}
catch (Exception ex)
{
//here process exception code
}
return isValid;
}
private bool signatureValidator(Dictionary<string, byte[]> dictP7SFiles,
Dictionary<string, byte[]> dictNotP7SFiles, X509Certificate2 userCertX509)
{
bool isValid = false;
try
{
byte[] data = dictP7SFiles["ZayavUL_3594c921f545406d9b8734bbe28bf894.doc"];
byte[] publicKey;
byte[] signature;
object hasher = SHA1.Create(); // Our chosen hashing algorithm.
// Generate a new key pair, then sign the data with it:
using (var publicPrivate = new RSACryptoServiceProvider())
{
signature = publicPrivate.SignData(data, hasher);
publicKey = publicPrivate.ExportCspBlob(false); // get public key
}
// Create a fresh RSA using just the public key, then test the signature.
using (var publicOnly = new RSACryptoServiceProvider())
{
publicOnly.ImportCspBlob(publicKey);
isValid = publicOnly.VerifyData(data, hasher, signature); // Return True
//isValid = ByteArrayCompare(dictP7SStreams["ZayavUL_3594c921f545406d9b8734bbe28bf894.doc_1.p7s"], signature);
byte[] p7sDetachedSignature = File.ReadAllBytes(@"D:\ZayavUL_3594c921f545406d9b8734bbe28bf894.doc_1.p7s");
isValid = ByteArrayCompare(p7sDetachedSignature, signature);
}
}
catch (Exception)
{
//here process exception code
}
return isValid;
}
Run Code Online (Sandbox Code Playgroud)
您做错的主要事情是重新生成CMS 和签名。您应该解析CMS 消息,然后在验证期间指示外部内容。
- 如何正确验证 .p7s 文件与其相应文件的分离签名?
看一下SO 上的以下 Java 代码,了解如何验证签名;C# 应该使用相同的体系结构,因此它应该以类似的方式工作。
- 在方法certificateValidator(参见下面的方法)中,如何验证从.p7s文件中提取的证书与从Base64格式的输入字符串中提取的证书的一致性?
解码 Base 64 证书并执行证书的链验证和验证。您想要执行多少验证(例如检查生效日期)取决于您。
- 代码行 foreach (X509Certificate2 x509 in signCms.Certificates) { } ---> 证书集合始终为空。为什么?
您只是在构建新的 CMS 结构期间没有放入其中之一。
您当然也不应该重新生成签名。通常,您在验证过程中不会拥有私钥,并且算法可能与 CMS 文档中使用的算法不匹配。此外,即使可以,签名生成也并不总是确定的(您可能会得到不同的签名值)。
| 归档时间: |
|
| 查看次数: |
3053 次 |
| 最近记录: |