在上一篇文章中,我们已经将密钥的生成方法和流程,归纳总结。而本篇主要是讲如何利用密钥进行加解密。

首先,在上一篇文章中的我们生成了很多密钥,证书等等。

在上述生成的文件中,接收服务端加密报文: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加解密的实际操作与流程小结的更多相关文章

  1. python实现RSA加密和签名以及分段加解密的方案

    1.前言 很多朋友在工作中,会遇到一些接口使用RSA加密和签名来处理的请求参数,那么遇到这个问题的时候,第一时间当然是找开发要加解密的方法,但是开发给加解密代码,大多数情况都是java,c++,js等 ...

  2. 学习加密(四)spring boot 使用RSA+AES混合加密,前后端传递参数加解密

      学习加密(四)spring boot 使用RSA+AES混合加密,前后端传递参数加解密 技术标签: RSA  AES  RSA AES  混合加密  整合   前言:   为了提高安全性采用了RS ...

  3. RSA加密通信小结(一)

    一.背景描述 帮朋友完成相关方案的改进. 二.计划与方案 1.加密方式采用RSA 1024加密. 2.发送与接收都采用RSA加密,采用两套不同的密钥. 3.统一的加解码函数.(此处除了对于传输数据进行 ...

  4. 调用OpenSSL实现RSA加解密和签名操作

    调用OpenSSL实现RSA加解密和签名操作 RSA公钥可以从证书和公钥文件,RSA私钥可以从私钥文件中提取.OpenSSL使用了一种BIO抽象IO机制读写所用文件,可以打开文件相关联的BIO,通过B ...

  5. Asp.Net Core 2.0 项目实战(7)MD5加密、AES&DES对称加解密

    本文目录 1. 摘要 2. MD5加密封装 3. AES的加密.解密 4. DES加密/解密 5. 总结 1.  摘要 C#中常用的一些加密和解密方案,如:md5加密.RSA加密与解密和DES加密等, ...

  6. RSA加密通信小结(三)--生成加解密所需的SSL命令与流程

    在iOS中使用RSA加密解密,需要用到.der和.p12后缀格式的文件,其中.der格式的文件存放的是公钥(Public key)用于加密,.p12格式的文件存放的是私钥(Private key)用于 ...

  7. RSA加密通信小结(二)-新版本APP与后台通信交互内容修改方案

    注1:本次修改分为两步,首先是内容相关的修改,待其完成之后,再进行加密通信项(粗体字备注)修改. 1.新的提交后台的格式包括:data,token(预留字段,暂时后台不校验),userId(已有的不删 ...

  8. rsa互通密钥对生成及互通加解密(c#,java,php)

    摘要 在数据安全上rsa起着非常大的作用,特别是数据网络通讯的安全上.当异构系统在数据网络通讯上对安全性有所要求时,rsa将作为其中的一种选择,此时rsa的互通性就显得尤为重要了. 本文参考网络资料, ...

  9. javascript的rsa加密和python的rsa解密

    先说下目前测试情况:javascript加密后的数据,python无法完成解密,我估计是两者的加密解密方法不同 1.看了这篇文章:http://blog.nsfocus.net/python-js-e ...

随机推荐

  1. string 学习

    #include <string> 1.取当中某个字符 与传统一样 c[11]="0123456789"; c[1]=1; ps:好慢 .. 会不会GG... #inc ...

  2. poj3160强连通分量加dfs

    After retirement as contestant from WHU ACM Team, flymouse volunteered to do the odds and ends such ...

  3. php函数每日学习二十个

    数学函数 1,abs() 求绝对值 2,ceil() 进一法取整 3,floor() 舍去法取整 4,fmod()对浮点数进行取余 例如fmod(5.7,1.3) 5,pow() 返回数的n次方 po ...

  4. 微软Build 2017第二天 .NET Standard 2.0 Preview 的客户端跨平台

    微软公司一年一度的开发者大会,即“Microsoft Build 2017”在总部西雅图正式开幕.按照官方安排,本次大会将持续 3 天,主题围绕微软公司各项最新技术成果的展示和研讨,包括与微软相关的产 ...

  5. 自己写的书《深入理解Android虚拟机内存管理》,不出版只是写着玩

    百度网盘地址:https://pan.baidu.com/s/1jI4xZgE 我给起的书名叫做<深入理解Android虚拟机内存管理>.本书分为两个部分,前半部分主要是我对Linux0. ...

  6. Jenkins+Tomcat+svn+maven自动化构建简单过程

    搭建好jenkins自动化构建之后,点击立即构建,即可将svn服务器上的源码自动编译构建,并打成war包,然后将这个war包以及编译好的项目复制到指定服务器的tomcat容器里,当svn服务器的代码有 ...

  7. VR市场爆炸-VR全景智慧城市

    随着VR的火爆,越来越多的企业开始关注这种高新技术,也有越来越多VR虚拟现实公司应运而生,但是VR虚拟现实公司真的那么好做吗?虽然VR虚拟现实拥有巨大的市场潜力,但是同时它也非常烧钱,如果VR虚拟现实 ...

  8. 数据结构与算法系列研究七——图、prim算法、dijkstra算法

    图.prim算法.dijkstra算法 1. 图的定义 图(Graph)可以简单表示为G=<V, E>,其中V称为顶点(vertex)集合,E称为边(edge)集合.图论中的图(graph ...

  9. 文本主题模型之LDA(三) LDA求解之变分推断EM算法

    文本主题模型之LDA(一) LDA基础 文本主题模型之LDA(二) LDA求解之Gibbs采样算法 文本主题模型之LDA(三) LDA求解之变分推断EM算法 本文是LDA主题模型的第三篇,读这一篇之前 ...

  10. Akka(2):Actor生命周期管理 - 监控和监视

    在开始讨论Akka中对Actor的生命周期管理前,我们先探讨一下所谓的Actor编程模式.对比起我们习惯的行令式(imperative)编程模式,Actor编程模式更接近现实中的应用场景和功能测试模式 ...