2010-12-01 162 views
2

我想在不使用任何第三方API的情况下发送加密和签名的邮件。 如果我只通过签名发送备用视图,Windows Mail可以验证它。如果我只使用加密数据的备用视图发送,Windows Mail可以解密它。但是,如果我同时发送,Windows Mail将获得2个附件。如果我签署encryptedBytes并将这些带符号的字节添加到替代视图,它只会验证签名,并且该消息是空的。 有什么想法?使用C#发送加密和签名的电子邮件

MailMessage message = new MailMessage(); 
message.From = new MailAddress(lblMail.Text); 
message.Subject = txtSubject.Text; 

string body = "Content-Type: text/plain\r\nContent-Transfer-Encoding: 7Bit\r\n\r\n" + structForm(); 

byte[] messageData = Encoding.ASCII.GetBytes(body); 
ContentInfo content = new ContentInfo(messageData); 
EnvelopedCms envelopedCms = new EnvelopedCms(content); 

message.To.Add(new MailAddress(provMail)); 

CmsRecipient recipient = new CmsRecipient(SubjectIdentifierType.SubjectKeyIdentifier, this.certificate); 
envelopedCms.Encrypt(recipient); 

byte[] encryptedBytes = envelopedCms.Encode(); 

SignedCms Cms = new SignedCms(new ContentInfo(encryptedBytes)); 
CmsSigner Signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, new X509Certificate2(@"c:\serv.pfx","123")); 

Cms.ComputeSignature(Signer); 
byte[] SignedBytes = Cms.Encode(); 

MemoryStream encryptedStream = new MemoryStream(encryptedBytes); 
AlternateView encryptedView = new AlternateView(encryptedStream, "application/pkcs7-mime; smime-type=signed--data;name=smime.p7m"); 
message.AlternateViews.Add(encryptedView); 
MemoryStream signedStream = new MemoryStream(SignedBytes); 
AlternateView signedView = new AlternateView(signedStream, "application/pkcs7-mime; smime-type=signed-data;name=sig.p7m"); 
message.AlternateViews.Add(signedView); 


System.Net.NetworkCredential SMTPUserInfo = new System.Net.NetworkCredential("[email protected]", "XXXXXX"); 
SmtpClient client = new SmtpClient("smtp.xpto.com"); 

client.UseDefaultCredentials = false; 
client.Credentials = SMTPUserInfo; 

client.Send(message); 

Label2.Text = "Assinado e cifrado!"; 

回答

3

您应该先签字,然后加密。

尽管最初的CMS和S/MIME规范允许您按任一顺序执行操作,但后来的工作指出,签署您无法阅读的文档是一个非常糟糕的主意。签名应该在纯文本上。


生成的MIME消息应该只有一个部分,它应该是S/MIME封装的数据。您的消息有两部分,加密部分被错误标记为带符号数据内容类型。创建并签署SignedCms对象。对其进行编码,并将编码后的值用作对象的内容。加密它,并使用其编码值作为MailMessage的内容,内容类型为“application/pkcs7-mime; smime-type = enveloped-data”。

+1

所以我确实在加密之前完成了签名。但是,它仍然是一样的效果。如果我只发送签名+加密,它不会很好 – 2010-12-01 01:20:34

相关问题