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 ...
随机推荐
- Postmark介绍
一. 引言 Postmark是由著名的NAS提供商NetApp开发,用来测试其产品的后端存储性能. Postmark主要用于测试文件系统在邮件系统或电子商务系统中性能,这类应用的特点是:需要频繁.大量 ...
- 原生JS-----论数据类型检测
常见的数据类型检测的方法: 一.最为基础的typeof 二.不可不知的instanceof 三.比instanceof更好的constructor 四.检测值或者表达式的结果是否为NaN 五.易用的j ...
- mysql5.7.16二进制安装
1.下载二进制文件 cd /data wget http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.16-linux-glibc2.5-x ...
- 为Android内核添加新驱动
转载地址:http://blog.chinaunix.net/uid-16759545-id-4892379.html 1. 在drives目录下添加hello目录,内含hello.c Kconfig ...
- .Net程序员学用Oracle系列(27):PLSQL 之游标、异常和事务
1.游标 1.1.游标属性 1.2.隐式游标 1.3.游标处理及案例 2.异常 2.1.异常类别 2.2.异常函数 2.3.异常处理及案例 3.事务 3.1.开始事务.结束事务 3.2.自治事务 3. ...
- 关于XML(可扩展标记语言)的基础知识与写法------2017-05-18
XML(Extensible Markup Language) HTML:超文本标记语言,主要用来展示 XML:可扩展标记语言,用来做数据传输XML特点: 1.树状结构,有且只有一个根 2.标签名 ...
- 微信小程序,前端大梦想(七)
微信小程序之数据缓存实例-备忘录 数据缓存在移动端的使用是非常重要的,既可以减少用户的流量支出又可以提高程序的访问速度和用户体验.每个微信小程序都可以有自己的本地缓存,可以通过 wx.setStora ...
- How to change current process to background process
Situation: there is a script or command is running, but we need to close current box/windows to do o ...
- New Adventure----GUI Design Studio
新建项目工程 File->New Project 新建设计文件 Project->New Design 单个设计文件的页面,F9运当前设计页面 页面控件中有绿色包围的控件为 ...
- scauoj 18025 小明的密码 数位DP
18025 小明的密码 时间限制:4000MS 内存限制:65535K提交次数:0 通过次数:0 题型: 编程题 语言: G++;GCC Description 小明的密码由N(1<=N& ...