邮件签名和加密

电子邮件是最常用的网络应用之一,已经成为人们信息交流的重要途径。电子邮件的来往一般是比IM更正规的一种交流,是严肃、严谨的一种方式,普通电子邮件以明文方式在网上传输、存储,存在巨大的安全风险,一直以来都是黑客重点攻击的目标,对信息安全构成重大威胁和挑战。

  同时各用户单位普遍使用的大多为传统邮件系统,缺乏安全设计,邮件数据明文传输和明文存储,安全性十分脆弱,存在着易泄密、易被监听和破解等严重安全隐患。整体来说缺乏系统性地实现防病毒、反垃圾、远程实时监测、恶意代码防范、攻击报警等安全监测保障功能,加上专业信息安全人员编制少,安全现状不容乐观。

  如何保障我们的信息安全,对于非专业人士非常的麻烦,S/MIME协议全称“安全的多功能互联网邮件扩展”(Secure/Multipurpose Internet Mail Extensions),是通过在RFCl847中定义的多部件媒体类型在MIME中打包安全服务的另一个技术。它提供验证、信件完整性、数字签名和加密。

  例如,微软Outlook已经从Outlook97就开始支持S/MIME;具体的使用就是在outlook上设置自己的默认签名加密证书,而在开发中我们也需要使用这个功能。在下图中展示了邮件的签名和加密。

  CMS/PKCS #7 提供 EnvelopedCms类来为邮件进行数字封装。使用 EnvelopedCms 类的一种 Encrypt 方法之一为邮件加密,CmsRecipient 类存储收件人的 X509 证书以及在邮件发件人和收件人之间建立会话密钥所用的技术。EnvelopedCms 类支持为多个收件人封装邮件。

 1 /// <summary>
 2         /// 证书加密
 3         /// </summary>
 4         /// <param name="clearText">加密的内容</param>
 5         /// <param name="certificate">加密的公钥</param>
 6         /// <returns></returns>
 7         static byte[] EncryptWithCertificate(byte[] clearText, X509Certificate2 certificate)
 8         {
 9             // create ContentInfo
10             ContentInfo contentInfo = new ContentInfo(clearText);
11             // EnvelopedCms represents encrypted data
12             //EnvelopedCms envelopedCms = new EnvelopedCms(contentInfo);
13             EnvelopedCms envelopedCms = new EnvelopedCms(contentInfo, new AlgorithmIdentifier(new Oid("AES256")));//3DES 指定的加密方式(可选择其他加密方式)
14             // add a recipient
15             CmsRecipient recipient = new CmsRecipient(certificate);
16             // encrypt data with public key of recipient
17             envelopedCms.Encrypt(recipient);
18             // create PKCS #7 byte array
19             // return encrypted data
20             return envelopedCms.Encode();
21         }

  使用 EnvelopedCms 类的 Decrypt 方法为封装的邮件解密。EnvelopedCms 邮件包含解决所需的收件人标识信息。该信息包含在 RecipientInfos 属性中。

 1 /// <summary>
 2         /// 证书解密
 3         /// </summary>
 4         /// <param name="cipherText">加密内容</param>
 5         /// <returns></returns>
 6         static byte[] DecryptWithCertificate(byte[] cipherText)
 7         {
 8             // create EnvelopedCms
 9             EnvelopedCms envelopedCms = new EnvelopedCms();
10             // deserialize PKCS#7 byte array
11             envelopedCms.Decode(cipherText);
12             // decryt data
13             envelopedCms.Decrypt();
14             // return plain text data
15             return envelopedCms.ContentInfo.Content;
16         }

  CMS/PKCS #7 提供 SignedCms 类来为邮件进行数字签名。使用 S/MIME 安全标准的电子邮件是一个说明如何使用 SignedCms 类提供安全性的示例。除了其他安全服务之外,S/MIME 还指定验证电子邮件发件人的真实性以及检查邮件本身的完整性的能力。

  可以使用 SignedCms 类的 ComputeSignature 方法之一计算邮件签名。SignedCms 邮件可以是“非分离式”,也可以是“分离式”,SignedCms.Detached确定是否分离邮件。SignedCms 邮件可以具有关联的签名特定的属性。这些属性可以签名,也可以不签名,Pkcs9SignTime签名时间属性就是可能使用的签名属性的示例。此属性包含邮件的签名时间。

 1         /// <summary>
 2         /// 签名
 3         /// </summary>
 4         /// <param name="clearText">签名内容</param>
 5         /// <param name="signingCertificate">签名证书(私钥)</param>
 6         /// <returns></returns>
 7         private static byte[] SignData(byte[] clearText, X509Certificate2 signingCertificate)
 8         {
 9             // create ContentInfo
10             ContentInfo contentInfo = new ContentInfo(clearText);
11
12             CmsSigner signer = new CmsSigner(signingCertificate);
13             //SHA256
14
15             //设置摘要算法
16             signer.DigestAlgorithm = new Oid("SHA256");
17
18             Pkcs9SigningTime pkcsTime = new Pkcs9SigningTime(DateTime.Now);
19             //设置签名时间
20             signer.SignedAttributes.Add(new AsnEncodedData(pkcsTime));
21
22             //创建确定是否分离签名
23             SignedCms signedCms = new SignedCms(SubjectIdentifierType.IssuerAndSerialNumber, contentInfo, false);
24
25             //如果此属性为 true,则分离签名。如果此属性为 false,则不分离签名。
26
27
28             // sign the data
29             signedCms.ComputeSignature(signer);
30             //signedCms.SignerInfos[0].RemoveCounterSignature(0);
31
32             // create PKCS #7 byte array
33             // return signed data
34             return signedCms.Encode();
35         }

   SignedCms 类的 CheckSignature 方法之一验证邮件签名、副署和签名属性。SignedCms 邮件包含验证所需的签名者证书。签名验证可否验证签名者证书,取决于这些方法的 verifySignatureOnly 参数的值。

 1 /// <summary>
 2         /// 验证签名和提取内容
 3         /// </summary>
 4         /// <param name="signedCmsAsBytes"></param>
 5         /// <param name="signingSubjects"></param>
 6         /// <returns></returns>
 7         static byte[] ValidateSignatureAndExtractContent(byte[] signedCmsAsBytes, ICollection<string> signingSubjects)
 8         {
 9             // create SignedCms
10             SignedCms signedCms = new SignedCms();
11             // deserialize PKCS #7 byte array
12             signedCms.Decode(signedCmsAsBytes);
13             // check signature
14             // false checks signature and certificate
15             // true only checks signature
16             signedCms.CheckSignature(true);
17             // access signature certificates (if needed)
18             foreach (SignerInfo signerInfo in signedCms.SignerInfos)
19             {
20                 X509Certificate2 signingCertificate = signerInfo.Certificate;
21                 signingSubjects.Add(signingCertificate.Subject);
22
23                 //signerInfo.SignedAttributes.
24                 foreach (var tempattr in signerInfo.SignedAttributes)
25                 {
26                     Oid tempoid = tempattr.Oid;
27                     byte[] strValueByte = tempattr.Values[0].RawData;
28                     string oidvalue = Encoding.UTF8.GetString(strValueByte, 0, strValueByte.Length);
29                 }
30
31             }
32
33             // return plain data without signature
34             return signedCms.ContentInfo.Content;
35         }

  上述签名代码中,可以更改签名方法,设置签名时间,同时签名和内容是可以分离开来的,同时在签名中也可以设置和读取其他属性,但目前本代码不支持,还在研究中。国内外相关的资料非常少,如找到相关代码,请不吝赐教,不胜感激。

原文地址:https://www.cnblogs.com/zuimengaitianya/p/9324643.html

时间: 2024-08-03 10:25:57

邮件签名和加密的相关文章

签名、加密、证书的基本原理和理解

最近开始接触后端PHP开发,里面涉及到的签名.加密.证书等概念弄得自己头晕眼花,最近查看了相关资料,下面把自己的理解写下来,有不对的地方,还请多指点指点. 数据传输安全的要满足的要求: 消息的发送方能够确定消息只有预期的接收方可以解密(不保证第三方无法获得,但保证第三方无法解密). 消息的接收方可以确定消息是由谁发送的(消息的接收方可以确定消息的发送方). 消息的接收方可以确定消息在途中没有被篡改过(必须确认消息的完整性). 对称加密 网络的数据传输从发送方发出到接收方接收到,要经过数个节点才能

对程序集“”签名时加密失败 --“对程序集签名时出错 - 拒绝访问。

选在强名称签名,编译程序集时出 [签名时加密失败 --“拒绝访问. ”]错误提示? 解决方法: 1.到”C:\ProgramData\Microsoft\Crypto\RSA”目录下面,选中:[MachineKeys]文件夹. 2.右键[MachineKeys]文件夹,在安全属性里面,将当前windows用户的权限加上. 3.回到vs.net 中,重新生成,问题解决.

Liunx 部署邮件TLS/SSL加密通信服务

部署邮件TLS/SSL加密通信服务 一.部署普通邮件服务器 1) 搭建并检测邮件服务的发送服务 [[email protected] ~]# rpm -q postfix postfix-2.10.1-6.el7.x86_64 [[email protected] ~]# netstat -pantu | grep :25 tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1822/ma

Security基础(三):OpenSSL及证书服务、邮件TLS/SSL加密通信

一.OpenSSL及证书服务 目标: 本案例要求熟悉OpenSSL工具的基本使用,完成以下任务操作: 使用OpenSSL加密/解密文件 搭建企业自有的CA服务器,为颁发数字证书提供基础环境 方案: 使用两台RHEL7虚拟机,其中svr7作为CA数字证书服务器,而pc207作为测试用客户机. 步骤: 步骤一:使用OpenSSL加密/解密文件 1)加密文件 创建一个明文的文本文件f1.txt,使用openssl进行加密,选用des3加密算法,输出的加密文件为f1.txt.enc . [[email 

邮件TLS/SSL加密通信

案例1:邮件TLS/SSL加密通信 1 案例1:邮件TLS/SSL加密通信1.1 问题 本案例要求为基于Postfix+Dovecot的邮件服务器提供加密通信支持,主要完成以下任务操作: 为SMTP服务(postfix)添加TLS/SSL加密通信支持 基于dovecot配置POP3s+IMAPS加密通信支持 客户端收发信测试,确保加密的邮件通信可用 1.2 方案 使用两台RHEL7虚拟机,其中svr7作为CA服务器,而mail作为测试用的Postfix+Dovecot邮件服务器.另外可准备一台p

angularJs自定义服务(实现签名和加密)

写在前面: angularJS是google公司主推的js开发优秀框架... 页面展示: 在应用中进行加密是普遍存在的,个人建议在前端实现加密签名(前端加密是否必要来自知乎:http://www.zhihu.com/question/25539382) 对base64.md5.sha1加密算法简单解释: 1.base64是可逆的.对称的加密算法:base64具有64个基本字符组成的基本字符集 base64加密原理: a.base64以3个字节为一组,而一个字节占8个位(bit) b.再把24bi

JDBC的配置文件,邮件,密码加密工具类

配置文件 url=jdbc:mysql:///sysclassName=com.mysql.jdbc.Driverusername=rootpassword=123456maxActive=5maxWait=5000initSize=3 import java.io.IOException;import java.security.MessageDigest;import java.util.Properties;import java.util.UUID; import javax.mail.

使用数字证书进行签名和加密解密

package com.jiaoyiping.passwordmanager.pki; import org.apache.commons.codec.binary.Hex; import javax.crypto.Cipher;import java.io.ByteArrayOutputStream;import java.io.DataOutputStream;import java.io.FileInputStream;import java.security.KeyStore;impor

对cookie-parser的理解(签名、加密)

1.为什么说要利用签名防止cookie被恶意篡改 我们在浏览器输入用户名和密码发送post请求到后端服务器,后端服务器验证合法,返回响应,并Set-Cookie为sessionid=***;username=water,然后浏览器接受到响应发Set-Cookie,于是将其存入内存或硬盘中:浏览器端再次发起请求,带上Cookie信息sessionid=***;username=water,请求修改自己的头像信息,服务器根据sessionid验证当前用户已登录,根据username,查找数据库中的对