1、数字信封的概念

数字信封,英文是Digital Envelope,望文生义,就可以知道将需要传递的数据,通过加密的方式包裹起来。

数字信封的准确定义,在《PKCS #7: Cryptographic Message Syntax Standard》标准的第10章中给出,原话是:“加密的内容,以及对内容解密的密钥被加密后的结果,这两者组合起来后,被称为数字信封”。

数字信封的组成如下图所示:

从上图可以看出,数字信封和我们日常生活中使用的信封,还是不一样的:日常生活中的信封,仅仅指包裹信件的外壳,不包含信件(内容);但数字信封其实是包含内容的。

2、数字信封的两种密钥

从概念介绍,我们可以看到数字信封其实有两种密钥:

密钥1:用于对内容进行加密和解密;

密钥2:用于对密钥1进行加密和解密。

由于需要处理的内容有可能很长,一般密钥1使用对称密钥,而且密钥1往往是临时(随机)生成;

密钥2则可以是对称密钥,也可以是非对称密钥:

如果是1对1发送信息,建议密钥2使用非对称密钥,发送者用公钥加密,接收者用私钥解密;

如果是1对多发送信息,建议密钥2使用对称密钥,发送者用对称密钥加密,接收者也用同样的密钥解密。

3、数字信封的通信原理

说到这里,即使不再介绍,大家也能猜出数字信封的通信原理了。

我还是画蛇添足,把数字信封的通信原理画出来(这里密钥1是对称密钥,密钥2则为最常用的非对称密钥):

4、Java语言实现数字信封

这里,我们使用JDK提供的加解密功能,对称加密算法为AES,非对称加密算法为RSA。

4.1 使用IDEA工具创建project_de工程,然后在project_de工程下建立digital_envelope模块

模块建立后,在IDEA中的显示如下:

4.2 新建一个数字信封类

数字信封类只有两个数据成员,加密后的内容,以及加密后的对称密钥。数字信封类的源代码如下:

package com.flying.digital_envelope;
public class DigitalEnvelope {byte[] encryptedKey;byte[] encryptedContent;
}

4.3 新建Sender类,表示发送方(甲方)

建立Sender对象时,需要传入消息内容,AES密钥,还有RSA的公钥。Sender对象将会生成一个数字信封。

Sender类的源代码如下:

package com.flying.digital_envelope;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.interfaces.RSAPublicKey;
public class Sender {private byte[] contentBytes;private byte[] aesKeyBytes;private RSAPublicKey rsaPublicKey;public Sender(byte[] contentBytes, byte[] aesKeyBytes, RSAPublicKey rsaPublicKey){this.contentBytes = contentBytes;this.aesKeyBytes = aesKeyBytes;this.rsaPublicKey = rsaPublicKey;}public DigitalEnvelope putMessageToEnvelope(){DigitalEnvelope digitalEnvelope = new DigitalEnvelope();try {SecretKeySpec secretKeySpec = new SecretKeySpec(aesKeyBytes, "AES");Cipher cipher = Cipher.getInstance("AES");cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);byte[] encrytedContent = cipher.doFinal(contentBytes);cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey);byte[] encryptedKey = cipher.doFinal(aesKeyBytes);digitalEnvelope.encryptedContent = encrytedContent;digitalEnvelope.encryptedKey = encryptedKey;}catch (Exception ex){ex.printStackTrace();}return digitalEnvelope;}
}

4.4 新建Receiver类,表示接收方(乙方)

建立Receiver对象时,需要传入数字信封和RSA私钥。Receiver对象将会解开数字信封,得到消息的内容。

Receiver类的源码如下:

package com.flying.digital_envelope;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.interfaces.RSAPrivateKey;
public class Receiver {private DigitalEnvelope digitalEnvelope;RSAPrivateKey rsaPrivateKey;public Receiver(DigitalEnvelope digitalEnvelope, RSAPrivateKey rsaPrivateKey){this.digitalEnvelope = digitalEnvelope;this.rsaPrivateKey = rsaPrivateKey;}public byte[] getMessageFromEnvelope(){byte[] contentBytes = null;try {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey);byte[] aesKeyBytes = cipher.doFinal(digitalEnvelope.encryptedKey);cipher = Cipher.getInstance("AES");SecretKeySpec secretKeySpec = new SecretKeySpec(aesKeyBytes, "AES");cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);contentBytes = cipher.doFinal(digitalEnvelope.encryptedContent);}catch (Exception ex){ex.printStackTrace();}return contentBytes;}
}

4.5 main方法

main方法在DigitalEnvelopeApplication类中提供,该类提供内容原文、AES密钥、RSA公钥和私钥,调用Sender和Receiver实现完整流程。

DigitalEnvelopeApplication类的源代码如下:

package com.flying.digital_envelope;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Base64;
@SpringBootApplication
public class DigitalEnvelopeApplication {public static void main(String[] args) {SpringApplication.run(DigitalEnvelopeApplication.class, args);try {byte[] aesKeyBytes = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};System.out.println("AES key: " + Base64.getEncoder().encodeToString(aesKeyBytes));KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(1024);KeyPair keyPair = keyPairGenerator.generateKeyPair();RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();byte[] contentBytes = "1234567890".getBytes();System.out.println("Before encryption, content bytes: " + Base64.getEncoder().encodeToString(contentBytes));Sender sender = new Sender(contentBytes, aesKeyBytes, rsaPublicKey);DigitalEnvelope digitalEnvelope = sender.putMessageToEnvelope();Receiver receiver = new Receiver(digitalEnvelope, rsaPrivateKey);byte[] decryptedContentBytes = receiver.getMessageFromEnvelope();System.out.println("After decryption, content bytes: " + Base64.getEncoder().encodeToString(decryptedContentBytes));}catch (Exception ex){ex.printStackTrace();}}
}

4.6 程序运行结果

下面是程序的某次运行结果:

AES key: AQIDBAUGBwgJCgsMDQ4PEA==
Before encryption, content bytes: MTIzNDU2Nzg5MA==
After decryption, content bytes: MTIzNDU2Nzg5MA==

根据结果,可以得知,数字信封的例子程序测试通过。

5、特别提示

上面的例子不建议商用

本讲提供的例子,主要用于讲解数字信封的概念,把这个例子看懂了,数字信封也基本上学会了。

但实际上,现在数字信封和数字证书捆绑得越来越紧,上面的例子用于学习没有问题,如果要实际商用,还得将数字证书的知识彻底掌握,然后在数字证书的环境中再次实现数字信封。

PKCS7数字信封简述相关推荐

  1. PKCS7带签名的数字信封

    结构体和示例说明 p7.pem文本内容示例: -----BEGIN PKCS7----- MIIFDAYKKoEcz1UGAQQCBKCCBPwwggT4AgEBMYIBJzCCASMCAQAwgZA ...

  2. PKCS1签名、PKCS7签名、PKCS数字信封

    1.1 PKCS#1签名 被签名的数据为字节数组.对给出的被签名原数据进行Hash运算,Hash结果按PKCS#1标准进行填充: B = 00 01 ff ff - ff 00 30 - H[00], ...

  3. java p7 数字签名,p7结构的数字信封 | 学步园

    PKCS7的数字信封格式分为两种:带签名的数字信封和不带签名的数字信封.由于这个数字信封的生成过程比较复杂,所以这两种格式比较容易记混,导致都搞不清楚一个数字信封里面到底是存储的什么内容了.下面我就详 ...

  4. sm2格式数字信封加解密详解

    sm2格式数字信封 0.参考链接 密码行业标准化技术委员会http://www.gmbz.org.cn/main/bzlb.html SM2密码算法使用规范http://www.gmbz.org.cn ...

  5. [转]密码技术-实现数字信封和数字签名

    密码技术-实现数字信封和数字签名 转载自:http://hi.baidu.com/king0332/item/ea9b19da597aec17e1f46f5b 数字信封是公钥密码体制在实际中的一个应用 ...

  6. java 数字信封_GitHub - zhopen/eos-crypto-java: EOS 公钥加密,私钥解密。基于ECC+AES 实现的双向验证加解密。数字信封的 加解密。...

    /** * * sender * * EOS8g1u3ktAGHs4QsVp9aeaWNebFLtprQHwpaSjegx6iEuoTNhjXU * 5KTZYCDdcfNrmEpcf97SJBCtT ...

  7. 密码学数字信封的介绍

    对称密码和非对称密码 对称密码:加解密运算非常快,适合处理大批量数据,但其密码的分发与管理比较复杂 非对称密码:公钥和私钥分离,非常适合密钥的分发和管理 数字信封的定义 如果将对称密码算法和非对称密码 ...

  8. 数字签名和数字信封之间的介绍

    介绍 公钥密码体制在实际应用中包含数字签名和数字信封两种方式 数字签名 指用户用自己的[私钥]对原始数据的哈希摘要进行加密所得的数据.数字签名定义两种互补的运算:一个用于签名,另一个用于验证.&quo ...

  9. 数字签名、数字信封、数字证书

    数字签名 发送方使用单向Hash把明文生成数字摘要(单向不可逆) 发送方使用自己的私钥加密数字摘要,形成数字签名 发送方把原始明文和数字签名一起发给接收方,接收方用发送方公钥对数字签名解密,得到数字摘 ...

最新文章

  1. 如何才能建立起似然函数
  2. 报名|首届中国智慧城市大数据开放创新应用大赛
  3. 将中缀表达式转化为后缀表达式
  4. c语言求n个数的最小值博客,C语言中的#define宏定义 求一组数的最大值和最小值(转)...
  5. 解决vc6.0卡死的方法
  6. CentOS 查看系统 CPU 个数、核心数、线程数
  7. DIP第六章习题解答
  8. pandas 判断数据表中的缺失值
  9. 食品工程计算机辅助设计,食品工程CAD技术应用及实例
  10. mysql index 信息_MySQL 索引
  11. html5+前端脸部识别采集,前端人脸识别框架Tracking.js
  12. 补充netty权威指南学习自定义协议实现,与springboot集成
  13. 相关系数excel_如何用Excel计算投资组合的有效前沿?
  14. 冰汽时代机器人不用热_如何评价游戏《冰汽时代》?
  15. 你所热爱的,就是你的生活
  16. WAMP安装与基础配置
  17. 增量式编码器和绝对式编码器
  18. 数理统计01:线性相关性系数,斯皮尔曼相关性系数计算及详解
  19. canvas绘制文字
  20. python设置画布大小_python-Tkinter画布自动调整大小

热门文章

  1. 手把手教你如何自己设计实现一个深度学习框架(附代码实现)
  2. tensorflow移植到Android端,实现物体检测自动拍照
  3. 计算 函数 f1 的定积分
  4. 选课系统 - 数据库查询(二)
  5. 语音信号分析(语音分帧)
  6. 《中国当代艺术“价值观” 》 高岭 (一)
  7. CorelDRAWX4的C++插件开发(三十八)纯C++插件开发(2)导入tlb编译文件
  8. Ubuntu16.04配置Leela zero(cpu版)
  9. 教你如何使用免费的域名来访问电脑搭建的服务器
  10. Aries(白羊座)框架的学习之路-1