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

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

在上述生成的文件中,接收服务端加密报文: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. bzoj 3028: 食物 -- 母函数

    3028: 食物 Time Limit: 3 Sec  Memory Limit: 128 MB Description 明明这次又要出去旅游了,和上次不同的是,他这次要去宇宙探险! 我们暂且不讨论他 ...

  2. 安装hexo报错(npm WARN deprecated swig@1.4.2: This package is no longer maintained),已解决

    问题:在使用npm安装hexo时报错 $ npm install -g hexo npm WARN deprecated swig@1.4.2: This package is no longer m ...

  3. Maven的简单搭建

    Maven这个个项目管理和构建自动化工具,越来越多的开发人员使用它来管理项目中的jar包.接下来将从下面几个方向介绍maven: (1)Maven简单介绍 (2)Maven安装与配置 (3)Maven ...

  4. servlet的执行原理与生命周期

    先从servlet容器说起:大家最为熟悉的servlet容器就是Tomcat ,Servlet 容器是如何管理 Servlet?先看一下tomcat的容器模型:从上图可以看出 Tomcat 的容器分为 ...

  5. protobuf那些事

    大家好,俺又来写博客了.......上次剧情预告说,这次会写hive的博客.......好吧,那俺就不打算写hive了.......老码农路子就是要野(本人不老,不能说得影响了找女票)......这次 ...

  6. springMVC---简介

    SpringMVC介绍 为什么要使用springMVC? 很多应用程序的问题在于处理业务数据和显示业务数据的视图的对象之间存在紧密耦合.通常,更新业务对象的命令都是从视图本身发起的,使视图对任何业务对 ...

  7. deepin/ubuntu下搭建Jekyll环境

    title: deepin/ubuntu下搭建Jekyll环境 最近用github搭建了个博客,正好也学习一下markdown语法,由于markdown写完后不是立即可见,所以每次写完文章都要经过在线 ...

  8. 【JQuery基础知识/statusCode(状态码)】---初学者必备

    今天,给大家分享一下JQuery的基础知识,简单介绍一下JQuery高级_Ajax,和我们常见的一些statusCode(状态码)~~~ 如果存在错误,请大家多多指正留言~小女子在此谢过! 一.JQu ...

  9. 多线程编程-- part 3 多线程同步->synchronized关键字

    多线程同时访问一个资源,可以会产生不可预料的结果,所以为这个资源加锁,访问资源的第一个线程为其加锁后,其他线程便不能在使用那个资源,直到锁被解除. 举个例子: 存款1000元,能取出800的时候我就取 ...

  10. SAS PROC MCMC example in R: Logistic Regression Random-Effects Model(转)

    In this post I will run SAS example Logistic Regression Random-Effects Model in four R based solutio ...