Java密码学
来源:互联网 发布:诺亚幻想 知乎 编辑:程序博客网 时间:2024/06/05 05:52
不知道数字信封的具体原理, 可以点击传送门
信息发送者首先利用随机产生的【对称密码】加密信息(因为非对称加密技术的速度比较慢),再利用接收方的【公钥】加密对称密码,被公钥加密后的对称密钥被称之为数字信封。在传递信息时,信息接收方要解密信息时,必须先用自己的私钥解密数字信封,得到对称密码,才能利用对称密码解密所得到的信息。
这里, 我们要的参数有以下
- 对称密钥或者对称密钥的生成算法
- 对方的公钥 (证书里含有)
- 正文(内容)
getCertificateChain这方式就是获取证书的array
证书的获取, 之前的文章里有提及, 使用pem格式也好, 使用keystore提取也好, 都可以.
CMSTypedData msg = new CMSProcessableByteArray(需要签名的内容);CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(cert)//证书(含公钥) .setProvider("BC")); CMSEnvelopedData ed = edGen.generate( msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC)//对称加密的算法 .setProvider("BC").build());
首先, 这段代码在BC的document或者源码都可以看到
org.bouncycastle.cms (Bouncy Castle Library 1.57 API Specification)
A package for processing RFC 3852 Cryptographic Message Syntax (CMS) objects - also referred to as PKCS#7 (formerly RFC 2630, 3369).
CMS是消息加密语法
1.数据处理
CMSTypedData msg = new CMSProcessableByteArray(content);
2.信封生成 (卧槽, 名字怎么这么长…)
CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider("BC"));edGen.generate( msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC) .setProvider("BC").build());
拆开来看
edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider("BC"));
是将证书里的内容提取出来, 再进行内容的转换成BC的结构 (原来是java.security的内容).
这里的信息有
- 公钥 (进行加密)
- Issuer 发行者 SerialNumber 发行者序列 (识别)
CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();CMSEnvelopedData ed = edGen.generate(数据,生成随机密钥);
3.返回CMSEnvelopedData信封加密数据
获取数字信封内容的代码
public byte[] openEnvelope(PrivateKey prikey) throws Exception { Security.addProvider(new BouncyCastleProvider()); PEMParser pr = new PEMParser(new FileReader(envfile)); ContentInfo o = (ContentInfo) pr.readObject();//读取PEM格式的数字信封 //获取密文 CMSEnvelopedData ed = new CMSEnvelopedData(o.getEncoded()); RecipientInformationStore recipients = ed.getRecipientInfos(); //解密 ArrayList list = (ArrayList) recipients.getRecipients(); RecipientInformation recipient = (RecipientInformation) list.get(0); return recipient.getContent(new JceKeyTransEnvelopedRecipient( prikey).setProvider("BC"));}
步骤
1.封装原始数据 (接收人信息+内容) ,并给了个引用接收人信息对象
CMSEnvelopedData ed = new CMSEnvelopedData(数字信封);
获得接收人信息, 并读取对应接收人等信息 (这里 ,我们可以知道, 接收人可以不止一个人, 只有对应的密钥才能解开)
我们就一个接收人, 所以读取第一个即可
RecipientInformationStore recipients = ed.getRecipientInfos();ArrayList list = (ArrayList) recipients.getRecipients();RecipientInformation recipient = (RecipientInformation) list.get(0);
算法等的准备完成后 ,接收私钥并完成解密
byte[] recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(私钥 ).setProvider("BC"));
PS: 这里有个坑, 就是代码需要设置BC作为提供者, 缺少是运行不了
Security.addProvider(new BouncyCastleProvider());
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- Java密码学
- 收藏.Java.密码学
- 程序员读书啦!!!
- 欢迎使用CSDN-markdown编辑器
- java 将源目录的所有文件(含子目录)拷贝到 目标目录中(运用File类实现)
- HDU 畅通工程&&还是畅通工程(查表法)
- [SMOJ2192]跳跃
- Java密码学
- apt-get&&逮捕重
- 全选 单选
- SHUOJ 新建 Microsoft Office Word 文档
- 记录一次设备更换的过程
- 关于哈希的总结
- uva11134 贪心
- 英语学习看自己
- 微积分拾遗——链式法则