一、概念
数字信封是将对称密钥通过非对称加密(即:有公钥和私钥两个)的结果分发对称密钥的方法。数字信封是实现信息保密性验证的技术。
二、过程描述
在数字信封中,信息发送方采用对称密钥来加密信息内容,然后将此对称密钥用接收方的公开密钥来加密(这部分称数字信封)之后,将它和加密后的信息一起发送给接收方,接收方先用相应的私有密钥打开数字信封,得到对称密钥,然后使用对称密钥解开加密信息。这种技术的安全性相当高。数字信封主要包括数字信封打包和数字信封拆解,数字信封打包是使用对方的公钥将加密密钥进行加密的过程,只有对方的私钥才能将加密后的数据(通信密钥)还原;数字信封拆解是使用私钥将加密过的数据解密的过程。
三、图解
四、代码示例
a.引入依赖
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.26</version>
</dependency><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15to18</artifactId><version>1.69</version>
</dependency>
b.代码
import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import cn.hutool.crypto.symmetric.SM4;
import java.io.Serializable;
import java.security.PrivateKey;
import java.security.PublicKey;/*** @Author 乐hh* @Description 数字信封测试**/
public class EnvelopeTest {public static void main(String[] args) {// 1.接收方生成一对公私钥(使用国密算法SM2)SM2 sm2 = SmUtil.sm2();PublicKey publicKey = sm2.getPublicKey(); // 公钥用于发送方加密PrivateKey privateKey = sm2.getPrivateKey(); // 私钥用于接收方解密// 2.发送方使用接收方的公钥生成数字信封Envelope envelope = generateEnvelope(publicKey);// 3.接收方使用私钥解密数字信封String message = openEnvelope(privateKey, envelope);System.out.println("信件内容:" + message);}/*** 生成数字信封* * @param publicKey SM2公钥* @return 数字信封*/private static Envelope generateEnvelope(PublicKey publicKey) {// 信件内容final String message = "Hello world!";// 使用对称密钥加密信件内容(使用国密算法SM4)SM4 sm4 = SmUtil.sm4();byte[] key = sm4.getSecretKey().getEncoded();String messageCipher = sm4.encryptBase64(message);// 使用公钥加密对称密钥SM2 sm2 = new SM2(null, publicKey);String keyCipher = sm2.encryptBase64(key, KeyType.PublicKey);return new Envelope(messageCipher, keyCipher);}/*** 打开数字信封** @param privateKey SM2私钥* @param envelope 数字信封* @return 信封内容*/private static String openEnvelope(PrivateKey privateKey, Envelope envelope) {// 使用私钥解密得到对称密钥SM2 sm2 = new SM2(privateKey, null);byte[] key = sm2.decrypt(Base64Decoder.decode(envelope.getKeyCipher()), KeyType.PrivateKey);// 使用对称密钥解密得到信件内容SM4 sm4 = new SM4(key);byte[] message = sm4.decrypt(Base64Decoder.decode(envelope.getMessageCipher()));return new String(message);}static class Envelope implements Serializable {/*** 信件内容密文(Base64编码)*/private String messageCipher;/*** 对称密钥密文(Base64编码)*/private String keyCipher;public Envelope(String messageCipher, String keyCipher) {this.messageCipher = messageCipher;this.keyCipher = keyCipher;}public String getMessageCipher() {return messageCipher;}public void setMessageCipher(String messageCipher) {this.messageCipher = messageCipher;}public String getKeyCipher() {return keyCipher;}public void setKeyCipher(String keyCipher) {this.keyCipher = keyCipher;}}
}
c.运行结果