RSA加密通信小结(四)--RSA加解密的实际操作与流程小结
在上一篇文章中,我们已经将密钥的生成方法和流程,归纳总结。而本篇主要是讲如何利用密钥进行加解密。
首先,在上一篇文章中的我们生成了很多密钥,证书等等。
在上述生成的文件中,接收服务端加密报文:pkcs8_private_key.pem给安卓使用解密,private_key.p12 给IOS使用解密(IOS加密是public_key.der文件),rsa_public_key.pem是JAVA服务器端使用的加密密钥(双向通信需要用两套不一样的密钥)。发送加密报文:rsa_public_key.pem给安卓使用加密,public_key.der给IOS使用加密,pkcs8_private_key.pem在服务器端进行解密密钥。
其次,打开密钥文件后,一般长这个样子。

于是为了将其利用起来,写了如下代码:

public static String readWantedText(String url) {
try {
FileReader fr = new FileReader(url);
BufferedReader br = new BufferedReader(fr);
StringBuffer sb = new StringBuffer();
String temp = "";// 用于临时保存每次读取的内容
temp = br.readLine();
while ((temp = br.readLine()) != null) {
if (temp.charAt(0) == '-') {
continue;
}
sb.append(temp);
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
获得以上密钥字符串之后,再将其转化为可用的密钥,转化私钥代码如下
public static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes = key.getBytes();
keyBytes = Base64.decodeBase64(keyBytes);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
转化公钥代码如下:
public static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes = key.getBytes();
keyBytes = Base64.decodeBase64(keyBytes);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
然后,得到了密钥之后我们进行加解密操作,其中一个重要的点就是117 可以参考此篇博文:http://www.metsky.com/archives/657.html,详细了解。这里关注点是,加密117字节加密 一下,解密用128解密。
加密函数如下:
public static final String KEY_ALGORITHM = "RSA";
private static final int MAX_ENCRYPT_BLOCK = 117;
private static final int MAX_DECRYPT_BLOCK = 128; public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
解密函数如下:
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)
throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
上两段代码中,涉及到的转码代码为:
public static byte[] decode(String base64) throws Exception {
return Base64.decode(base64.getBytes());
}
public static String encode(byte[] bytes) throws Exception {
return new String(Base64.encode(bytes));
}
由此 我们就完成了对密钥的使用,现在我们通过一个简单的测试代码来检验我们这几篇文档的成果。
public static void main(String[] args) {
String publicFilePath = "E:\\test_public_key.pem";
String publickey = RSAForCommunication.readWantedText1(publicFilePath);
String word = "这是用来测试,加密效果的一句话,可以试试 有多长。但是目前的情况来看,是可以长场产出噶哈哈哈哈哈哈哈哈啊哈哈哈哈哈啊哈哈哈哈啊啊啊哈哈哈";
String encode ="";
try {
byte[] a = RSAForCommunication.encryptByPublicKey(word.getBytes(), publickey);
encode = Base64Utils.encode(a);
} catch (Exception e) {
}
System.out.println("-------加密之后的密文:");
System.out.println(encode);
String filePath = "E:\\test_private_key.pem";
String key = RSAForCommunication.readWantedText1(filePath);
byte[] a;
try {
a = Base64Utils.decode(encode);
byte[] b = decryptByPrivateKey(a, key);
String deCodeStr = new String(b, "utf-8");
System.out.println("--------密文解密为:");
System.out.println(deCodeStr);
} catch (Exception ex) {
System.out.println("1");
}
}
结果展示
最后,这里的密文在传输过程中会出现空格或者被转义的情况,请注意!这是因为安卓或者IOS使用了通信框架或者其他原因导致。会使得通信失败
如果你有更好的加解密办法请联系我。
——————————————————————————————————————————
补充
关于Base64的包 不建议使用 sun.misc.BASE64Encoder这个包,具体的原因是由于SUN公司卖给oracle之前,自己定义的一些类。并不在公布的API中,以后随时可能被删除掉,所以不建议使用。
建议使用 ,如:org.apache.commons.codec.binary.Base64类
RSA加密通信小结(四)--RSA加解密的实际操作与流程小结的更多相关文章
- python实现RSA加密和签名以及分段加解密的方案
1.前言 很多朋友在工作中,会遇到一些接口使用RSA加密和签名来处理的请求参数,那么遇到这个问题的时候,第一时间当然是找开发要加解密的方法,但是开发给加解密代码,大多数情况都是java,c++,js等 ...
- 学习加密(四)spring boot 使用RSA+AES混合加密,前后端传递参数加解密
学习加密(四)spring boot 使用RSA+AES混合加密,前后端传递参数加解密 技术标签: RSA AES RSA AES 混合加密 整合 前言: 为了提高安全性采用了RS ...
- RSA加密通信小结(一)
一.背景描述 帮朋友完成相关方案的改进. 二.计划与方案 1.加密方式采用RSA 1024加密. 2.发送与接收都采用RSA加密,采用两套不同的密钥. 3.统一的加解码函数.(此处除了对于传输数据进行 ...
- 调用OpenSSL实现RSA加解密和签名操作
调用OpenSSL实现RSA加解密和签名操作 RSA公钥可以从证书和公钥文件,RSA私钥可以从私钥文件中提取.OpenSSL使用了一种BIO抽象IO机制读写所用文件,可以打开文件相关联的BIO,通过B ...
- Asp.Net Core 2.0 项目实战(7)MD5加密、AES&DES对称加解密
本文目录 1. 摘要 2. MD5加密封装 3. AES的加密.解密 4. DES加密/解密 5. 总结 1. 摘要 C#中常用的一些加密和解密方案,如:md5加密.RSA加密与解密和DES加密等, ...
- RSA加密通信小结(三)--生成加解密所需的SSL命令与流程
在iOS中使用RSA加密解密,需要用到.der和.p12后缀格式的文件,其中.der格式的文件存放的是公钥(Public key)用于加密,.p12格式的文件存放的是私钥(Private key)用于 ...
- RSA加密通信小结(二)-新版本APP与后台通信交互内容修改方案
注1:本次修改分为两步,首先是内容相关的修改,待其完成之后,再进行加密通信项(粗体字备注)修改. 1.新的提交后台的格式包括:data,token(预留字段,暂时后台不校验),userId(已有的不删 ...
- rsa互通密钥对生成及互通加解密(c#,java,php)
摘要 在数据安全上rsa起着非常大的作用,特别是数据网络通讯的安全上.当异构系统在数据网络通讯上对安全性有所要求时,rsa将作为其中的一种选择,此时rsa的互通性就显得尤为重要了. 本文参考网络资料, ...
- javascript的rsa加密和python的rsa解密
先说下目前测试情况:javascript加密后的数据,python无法完成解密,我估计是两者的加密解密方法不同 1.看了这篇文章:http://blog.nsfocus.net/python-js-e ...
随机推荐
- [进程管理] 理解 Linux 的处理器负载均值
原文链接: http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages http://www.gracecode. ...
- 如何使用python生成xml
最近要用python生成一个xml格式的文件.因为有一些内容是中文,原来的xml文件中使用了CDATA 的部分. 而之前的python程序所用的库中没有 创建这个区域的方法.无奈研究了大半天. 最后用 ...
- Omi树组件omi-tree编写指南
Omi框架能够以少量的代码声明式地编写可拖拽移动节点的树形组件. 通常树组件能够考验UI框架的健壮性,因为需要使用到UI框架的如下特性: 组件嵌套 组件传值 组件批量传值 组件依赖自身递归嵌套(nes ...
- 在 ubuntu 下优雅的使用 Sublime Text 3 写 Python
此文章非技术文,就是一些对于 Sublime 俺之前经常用的 方法(快捷键 )和 工具 有一些工具俺也用过,但是效果不太好,可以说跟shi 一样,可能每个人的用处不一样,咱就不提了,免得招 来口舌之争 ...
- JavaEE开发之SpringBoot整合MyBatis以及Thymeleaf模板引擎
上篇博客我们聊了<JavaEE开发之SpringBoot工程的创建.运行与配置>,从上篇博客的内容我们不难看出SpringBoot的便捷.本篇博客我们继续在上篇博客的基础上来看一下Spri ...
- ST-4
1.(49-7)使用下面的方法printPrimes()完成后面的问题: (a)为printPrimes()方法画控制流图. (b)考虑测试用例t1=(n=3)和t2=(n=5).即使这些测试用例游历 ...
- 使用JS开发桌面端应用程序NW.js-1-Menu菜单的使用小记
前言 本文主要内容为nw.js官方文档中没有提到,而在实际入手开发过程中才碰到的问题以及经验的汇总. 详情请查看官方文档:http://docs.nwjs.io/en/latest/Reference ...
- 如何用Ettercap实现“中间人攻击”(附下载链接)
什么是“中间人攻击”? 中间人攻击(Man-in-the-Middle Attack,简称“MiTM攻击”)是一种“间接”的入侵攻击,这种攻击模式是通过各种技术手段将受入侵者控制的一台计算机虚拟放置在 ...
- JAVA进程占用CPU分析
在一次生产环境中,服务器负载报警,SSH登录上看到CPU占用很高. 1.执行top命令,看到进程号为9737的进程持续占用CPU 2.怀疑是否是进程配置的内存不够了,引发了fullGC导致CPU占用高 ...
- 终端的CTRL+S 解说
在很多类Unix 的系统上,Ctrl-S 都有特殊的含义:它会"冻结"终端(它曾 经被用来暂停快速滚动).因为"保存"一般也是用这个快捷键,所以经常 会有人不假 ...