C# 如何验证来自电子邮件的数字签名(编码 SeveBit)

Posted

技术标签:

【中文标题】C# 如何验证来自电子邮件的数字签名(编码 SeveBit)【英文标题】:C# How to Verify Digital Signature from email ( Encoding SeveBit ) 【发布时间】:2011-11-22 18:17:24 【问题描述】:

我得到消息正文和包含数字签名的 smime.p7s 文件。我想验证邮件是否由该签名签名。 我正在使用以下代码。

   private bool VerifyCommand(string text, byte[] signature, string certPath)
   
// Load the certificate file to use to verify the signature from a file
// If using web service or ASP.NET, use: X509Certificate2 cert = new X509Certificate2(Request.ClientCertificate.Certificate);
X509Certificate2 cert = new X509Certificate2(certPath);

// Get public key
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PublicKey.Key;

// Hash the text, the text is the expected command by the client application.
// Remember hased data cannot be unhash. It is irreversable
SHA1Managed sha1 = new SHA1Managed();
UnicodeEncoding encoding = new UnicodeEncoding();
byte[] data = encoding.GetBytes(text);
byte[] hash = sha1.ComputeHash(data);

// Verify the signature with the hash
return csp.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), signature);

byte[] signature 是在 Convert.FromBase64String(mailsignature) 之后来自邮件的签名。 string certPath 是 smime.p7s 文件的路径。 (smime.p7s 附在邮件中)

这是正文所在的部分:

------=_NextPart_001_0039_01CC77C1.AFC97230
Content-Type: text/plain;
    charset="us-ascii"
Content-Transfer-Encoding: 7bit

FINAL TEST SIGNED

------=_NextPart_001_0039_01CC77C1.AFC97230

这是签名附件的一部分:

------=_NextPart_000_0038_01CC77C1.AFC4B740
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"

MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIWADCCA7Ew
ggKZoAMCAQICEBErBTlXKN63QvT+VRPTt1EwDQYJKoZIhvcNAQEFBQAwQzEXMBUGA1UEChMOQWxj
YXRlbCBMdWNlbnQxKDAmBgNVBAMTH0FsY2F0ZWwgTHVjZW50IEludGVybmFsIFJvb3QgQ0EwHhcN
MDgxMTAzMTU0MTE2WhcNMjgxMTAzMTU0MTE2WjBDMRcwFQYDVQQKEw5BbGNhdGVsIEx1Y2VudDEo
MCYGA1UEAxMfQWxjYXRlbCBMdWNlbnQgSW50ZXJuYWwgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAL5IGBVth8afQdnpuLDI0Z37GgIcPWznOOzFJUV1gVbztqQ5CIxkVL4K
...................

我使用的方法是否正确?是编码写的?还是我必须使用 7 位?

在此处输入代码


谢谢亨宁克劳斯。我搜索了一下,我又卡住了:(。

public static bool Verify(byte[] signature, X509Certificate2 certificate)

   X509Certificate2 cert=new X509Certificate2(@"D:\Work\Digital Signature\smime.p7s");
   certificate = cert;

    if(signature == null)
        throw new ArgumentNullException("signature");
    if(certificate == null)
        throw new ArgumentNullException("certificate");

    //the text from the body of the mail    
    string text = "FINAL TEST SIGNED";
    //hash the text 
     // Methode 3 for Hashing
            System.Security.Cryptography.SHA1 hash3 = System.Security.Cryptography.SHA1.Create();
            System.Text.UnicodeEncoding encoder = new System.Text.UnicodeEncoding();
            byte[] combined = encoder.GetBytes(text);
            byte[] hash3byte = hash3.ComputeHash(combined);

    //Adding the text from the email, to a contentInfo 
      ContentInfo content = new ContentInfo(hash3byte);

    // decode the signature
    SignedCms verifyCms = new SignedCms(content,true);
    verifyCms.Decode(signature);

    // verify it
    try
    
        verifyCms.CheckSignature(new X509Certificate2Collection(certificate), false);
        return true;
    
    catch(CryptographicException)
    
        return false;
    
 

我收到 CryptographicException“哈希值不正确”。 我只试过verifyCms.CheckSignature(true); (同样的错误) 我试图在 ContentInfo 中添加整个邮件(发件人、主题、正文、html Sectione ...)(同样的错误)

您能否更具体地说明如何使用 SignedCms 解决我的问题?

【问题讨论】:

【参考方案1】:

您应该查看SignedCMS 类。您可以使用该类根据 PKCS#7 标准验证签名。

如果您有消息和签名,您将执行以下操作:

var cmsMessage = new SignedCms(new ContentInfo(message), true)
cmsMessage.Decode(signature);
// if no CryptographicException is thrown at this point, the signature holds up. Otherwise it's broken.

【讨论】:

我把我的例子贴出来了。你能给我一个具体的例子吗?

以上是关于C# 如何验证来自电子邮件的数字签名(编码 SeveBit)的主要内容,如果未能解决你的问题,请参考以下文章

表单 验证,手机 ,QQ,电子邮箱,数字,邮政编码,身份证,手机号 & 电话

使用 C# 发送加密和签名的电子邮件

Microsoft 帐户 JWT 身份验证令牌如何签名?

JS进行Base64编码,MD5加密,URL编码实现快递鸟API接口签名验证

Bitstamp - C# 中的新身份验证 - 签名

C# 字符串 数据类型 判断 与特定规则验证