C# 如何验证电子邮件中的数字签名?
如果签名有效,我打算从EmailMessage对象(Microsoft.Exchange…)中提取附件。 这是我的测试邮件:C# 如何验证电子邮件中的数字签名?,c#,digital-signature,verification,mime-message,C#,Digital Signature,Verification,Mime Message,如果签名有效,我打算从EmailMessage对象(Microsoft.Exchange…)中提取附件。 这是我的测试邮件: MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=SHA1; boundary="----=_NextPart_000_0039_01D1C7DA.CFEBF380" This is a multipart message
MIME-Version: 1.0
Content-Type: multipart/signed;
protocol="application/x-pkcs7-signature";
micalg=SHA1;
boundary="----=_NextPart_000_0039_01D1C7DA.CFEBF380"
This is a multipart message in MIME format.
------=_NextPart_000_0039_01D1C7DA.CFEBF380
Content-Type: multipart/mixed;
boundary="----=_NextPart_001_003A_01D1C7DA.CFEBF380"
------=_NextPart_001_003A_01D1C7DA.CFEBF380
Content-Type: multipart/alternative;
boundary="----=_NextPart_002_003B_01D1C7DA.CFEBF380"
------=_NextPart_002_003B_01D1C7DA.CFEBF380
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
{body text ...}
------=_NextPart_002_003B_01D1C7DA.CFEBF380
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
{html formating ...}
------=_NextPart_002_003B_01D1C7DA.CFEBF380--
------=_NextPart_001_003A_01D1C7DA.CFEBF380
Content-Type: application/octet-stream;
name="s15sq07 - clearing & margining.sql"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="s15sq07 - clearing & margining.sql"
{file content in base64 ...}
------=_NextPart_001_003A_01D1C7DA.CFEBF380--
------=_NextPart_000_0039_01D1C7DA.CFEBF380
Content-Type: application/pkcs7-signature;
name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="smime.p7s"
{signature ...}
------=_NextPart_000_0039_01D1C7DA.CFEBF380--
签名验证的原理如下:计算消息(m)的散列(H(m))并使用发送方公钥(pubk)和验证函数(V)将结果与签名(sig)进行比较
表示V_pubk(H(m))=sig
我的代码:
private static bool iDoHandleMail( EmailMessage msg )
{
try
{
msg.Load( new PropertySet( EmailMessageSchema.Attachments ) );
foreach ( Attachment att in msg.Attachments )
{
FileAttachment fatt = att as FileAttachment;
if ( fatt == null )
continue;
using ( MemoryStream ms = new MemoryStream( ) )
{
fatt.Load( ms );
ms.Position = 0;
MimeKit.MimeMessage mmsg = MimeKit.MimeMessage.Load( ms );
我试过了,(页面底部):
然后我尝试了这个,但没有成功:
MimeEntity sig = mmsg.BodyParts.Where(x => x.IsAttachment && x.ContentType.Name != null && x.ContentType.Name.EndsWith(".p7s")).Select(x => x).ToArray()[0];
MIME.MimeMessage mSig = new MIME.MimeMessage();
mSig.LoadBody(sig.ToString());
string cont = mSig.mContent;
byte[] siCont = enc.GetBytes(cont);
byte[ ] siCont64 = Convert.FromBase64String( cont );
foreach ( MimeEntity me in mmsg.BodyParts )
{
if ( !me.IsAttachment ) continue;
using ( MemoryStream ms2 = new MemoryStream( ) )
{
me.WriteTo( ms2 );
ms2.Position = 0;
MIME.MimeMessage msg2 = new MIME.MimeMessage();
msg2.LoadBody(me.ToString());
byte[] textb = enc.GetBytes(msg2.mContent);
byte[] hashb = sha.ComputeHash(textb);
ContentInfo inf = new ContentInfo(hashb);
SignedCms cms = new SignedCms(inf, true);
cms.Decode(siCont64);
try
{
// CertificateManager is a custom class and returns a X509Certificate2-Collection based on a config in my app
cms.CheckSignature( CertificateManager.GetCertificate( cfg ), false );
MessageBox.Show("luck");
}
catch ( Exception ex )
{
// hash is always wrong
}
}
}
现在我已经到了无法再思考的地步
MimeEntity sig = mmsg.BodyParts.Where(x => x.IsAttachment && x.ContentType.Name != null && x.ContentType.Name.EndsWith(".p7s")).Select(x => x).ToArray()[0];
MIME.MimeMessage mSig = new MIME.MimeMessage();
mSig.LoadBody(sig.ToString());
string cont = mSig.mContent;
byte[] siCont = enc.GetBytes(cont);
byte[ ] siCont64 = Convert.FromBase64String( cont );
foreach ( MimeEntity me in mmsg.BodyParts )
{
if ( !me.IsAttachment ) continue;
using ( MemoryStream ms2 = new MemoryStream( ) )
{
me.WriteTo( ms2 );
ms2.Position = 0;
MIME.MimeMessage msg2 = new MIME.MimeMessage();
msg2.LoadBody(me.ToString());
byte[] textb = enc.GetBytes(msg2.mContent);
byte[] hashb = sha.ComputeHash(textb);
ContentInfo inf = new ContentInfo(hashb);
SignedCms cms = new SignedCms(inf, true);
cms.Decode(siCont64);
try
{
// CertificateManager is a custom class and returns a X509Certificate2-Collection based on a config in my app
cms.CheckSignature( CertificateManager.GetCertificate( cfg ), false );
MessageBox.Show("luck");
}
catch ( Exception ex )
{
// hash is always wrong
}
}
}