非对称加密之RSA算法

  • 1. RSA算法简述
  • 2. 模型分析
  • 3.代码实现
    • 3.1 算法实现
    • 3.2 测试代码
    • 3.3 测试结果
  • 4. 算法实现分析
  • 5. 数据分段处理

该系列文章列表

1.网络及数据安全概念及领域概述
网络安全之数据加密/解密/签名/验签/数字证书
2.对称加密/解密算法
对称加密算法之高级数据加密标准-AES
对称加密之三重DES—DESede
对称加密算法之DES

3.非对称加密/解密算法
非对称加密算法概述
非对称加密之密钥交换算法-DH
非对称加密之RSA算法
非对称加密之Curve25519加密算法
4.其他加密解密算法
异或加密算法
5. 消息摘要算法
SHA安全散列算法
6. 数字证书
7. 网络安全协议

1. RSA算法简述

在DH算法的基础上,RSA算法、ElGamal算法及ECC算法等被提出。
RSA算法基于大数因子分解难题, 而ElGamal算法和ECC算法则是基于离散对数难题。
目前,主流计算机语言都提供了对RSA算法的支持。Java中可以很方便地构建该算法。

RSA在1978年,由麻省理工学院(MIT)的Ron Rivest、Adi Shamir和Leonard Adleman三位学者提出,以三位学者姓氏开头字母命名,被成为RSA算法。

RSA算法是唯一被广泛接受并实现的通用公开加密算法,目前已经成为非对称加密算法国际标准。RSA算法也被用于数字签名。

RSA想对于对称加密算法而言,其算法速度要慢得多。

RSA算法是最流行的公钥密码算法,使用长度可以变化的密钥。

2. 模型分析

下面以Alice与Bob双方收发消息为例,说明是RSA进行数据加密/解密的交互流程。这里Alice作为消息发送方,Bob作为消息接收方。Alice与Bob双方在消息传递之前已将RSA算法作为消息传递的加密算法。具体交互流程如下:

  1. 密钥构建及发布

步骤1、2为密钥构建及发布流程。

  1. 构建加密消息传递

步骤3、4、5为构建加密消息传递流程, Alice(发送者)向Bob(接收者)发送RSA算法加密数据

步骤6、7、8, Bob(接收者)向Alice(发送者)回复RSA算法加密的数据

特别说明:非对称加密算法领域中,对于私钥加密的数据只能使用公钥解密。对于公钥加密的数据,只能使用私钥解密。
简言之,“私钥加密,公钥解密”或者“公钥加密,私钥解密”。

在传递过程中,公钥可能被截获,截获的加码数据也可能被破解。所以要建立更安全的加密消息传递模型,就需要甲乙方构建两套非对称加密算法密钥,仅遵循“私钥加密,公钥解密”的方式进行加密消息传递。

3.代码实现

RSA算法较DH算法在密钥管理及实现上较为简单,一方面,甲方保留了私钥,而将公钥公布于乙方,甲乙双方密钥一一对应; 另一方面,私钥用于解密,公钥则用于加密,反之亦然。RSA算法仅需要一套密钥即可完成加密/解密操作。Java与Bouncy Castle都对RSA提供了实现,具体实现细节如下:

算法 密钥长度 密钥默认长度 工作模式 填充模式 备注
RSA 512~65536位(密钥长度必须是64的倍数) 1024 ECB NoPadding、PKCS1Padding、OAEPWITHMD5AndMGF1Padding、 OAEPWITHSHA1AndMGF1Padding、OAEPWITHSHA256AndMGF1Padding、OAEPWITHSHA384AndMGF1Padding、OAEPWITHSHA512AndMGF1Padding Java6
RSA 512~65536位(密钥长度必须是64的倍数) 2048 NONE NoPadding、PKCS1Padding、OAEPWITHMD5AndMGF1Padding、 OAEPWITHSHA1AndMGF1Padding、OAEPWITHSHA224AndMGF1Padding、OAEPWITHSHA256AndMGF1Padding、OAEPWITHSHA384AndMGF1Padding、OAEPWITHSHA512AndMGF1Padding、ISO9796-1Padding Bouncy Castle实现

3.1 算法实现

算法基于Java的实现

package com.calvin.android.secrity;/*** Author:cl* Email:lhzheng@grandstream.cn* Date:20-10-20*/import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;import javax.crypto.Cipher;/*** RSA安全编码组件*/
public class RSACoder {//密钥生成算法public static final String KEY_ALGORITHM = "RSA";//数据加密算法public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";//加密填充方式//公钥 Map Keyprivate static final String PUBLIC_KEY = "RSAPublicKey";//私钥Map keyprivate static final String PRIVATE_KEY = "RSAPrivateKey";/*** RSA密钥长度,默认1024位,密钥长度必须是64的倍数,范围512~65536位之间*/private static final int KEY_SIZE = 512;/*** 私钥解密* @param data 待解密数据* @param key 私钥* @return byte[] 解密数据* @throws Exception 异常*/public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {//取得私钥PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//生成私钥PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);//对数据解密//指定具体加密算法时 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);}/*** 私钥加密* @param data 待加密数据* @param key 私钥* @return byte[] 加密数据* @throws Exception 异常*/public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {//取得私钥PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//生成私钥PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);//对数据加密 //指定具体加密算法时 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, privateKey);return cipher.doFinal(data);}/*** 公钥解密* @param data 待解密数据* @param key 公钥* @return byte[] 解密数据* @throws Exception 异常*/public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception {//取得公钥X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//生成公钥PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);//对数据解密//指定具体加密算法时 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, publicKey);return cipher.doFinal(data);}/*** 公钥加密* @param data 待加密数据* @param key 公钥* @return byte[] 加密数据* @throws Exception 异常*/public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {//取得公钥X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//生成公钥PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);//对数据解密//指定具体加密算法时 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicKey);return cipher.doFinal(data);}public static Map<String, Object> initKey() throws Exception {//实例化密钥对生成器KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);//初始化密钥对生辰其keyPairGen.initialize(KEY_SIZE);//生成密钥对KeyPair keyPair = keyPairGen.generateKeyPair();//公钥RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();//私钥RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();//封装密钥Map<String, Object> keyMap = new HashMap<>(2);keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;}public static byte[] getPublicKey(Map<String, Object> keyMap){return  ((RSAPublicKey)keyMap.get(PUBLIC_KEY)).getEncoded();}public static byte[] getPrivateKey(Map<String, Object> keyMap){return  ((RSAPrivateKey)keyMap.get(PRIVATE_KEY)).getEncoded();}
}

3.2 测试代码

android 单元测试代码

@Testpublic void RSATest() throws Exception {//初始化密钥Map<String, Object> keyMap = RSACoder.initKey();byte[] publicKey = RSACoder.getPublicKey(keyMap);byte[] privateKey = RSACoder.getPrivateKey(keyMap);System.out.println("公钥:\n"+Base64.encodeToString(publicKey, Base64.DEFAULT));System.out.println("私钥:\n"+Base64.encodeToString(privateKey, Base64.DEFAULT));System.out.println("\n ----私钥加密--公钥解密----");String inputStr1 = "RSA加密算法";byte[] data1 = inputStr1.getBytes();System.out.println("原文:\n "+inputStr1);//加密byte[] encodedData1 = RSACoder.encryptByPrivateKey(data1, privateKey);System.out.println("加密后:\n "+Base64.encodeToString(encodedData1, Base64.DEFAULT));//解密byte[] decodedData1 = RSACoder.decryptByPublicKey(encodedData1, publicKey);String outputStr1 = new String(decodedData1);System.out.println("解密后:\n "+outputStr1);assertEquals(inputStr1, outputStr1);System.out.println("\n ----公钥加密--私钥解密----");String inputStr2 = "RSA Encrypt Algorithm";byte[] data2 = inputStr2.getBytes();System.out.println("原文:\n "+inputStr2);//加密byte[] encodedData2 = RSACoder.encryptByPublicKey(data2, publicKey);System.out.println("加密后:\n "+Base64.encodeToString(encodedData2, Base64.DEFAULT));//解密byte[] decodedData2 = RSACoder.decryptByPrivateKey(encodedData2, privateKey);String outputStr2 = new String(decodedData2);System.out.println("解密后:\n "+outputStr2);//校验证assertEquals(inputStr2, outputStr2);}

3.3 测试结果

android7.0下的运行结果

2020-10-20 09:57:42.066 4810-4827/com.calvin.android.sample I/System.out: 公钥:
2020-10-20 09:57:42.066 4810-4827/com.calvin.android.sample I/System.out: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL5gzKOXMyj7+YAxYzxtjfmsWIviUATR/zTms4YoHGNu
2020-10-20 09:57:42.066 4810-4827/com.calvin.android.sample I/System.out: gyia00naRS0QDm2Q0iMMWdwgEHrLQT6IoW+nnWWlqwcCAwEAAQ==
2020-10-20 09:57:42.066 4810-4827/com.calvin.android.sample I/System.out: 私钥:
2020-10-20 09:57:42.066 4810-4827/com.calvin.android.sample I/System.out: MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggE8AgEAAkEAvmDMo5czKPv5gDFjPG2N+axYi+JQ
2020-10-20 09:57:42.066 4810-4827/com.calvin.android.sample I/System.out: BNH/NOazhigcY26DKJrTSdpFLRAObZDSIwxZ3CAQestBPoihb6edZaWrBwIDAQABAkAjy0tujqUd
2020-10-20 09:57:42.066 4810-4827/com.calvin.android.sample I/System.out: 1ZJpmd+QowCIqvDTDDADWABlz+J9HNmJkBA5w/Npg3eu5rYIZo9mkOtEp8A74ghQIJrN1BeoiNHx
2020-10-20 09:57:42.066 4810-4827/com.calvin.android.sample I/System.out: AiEA9Wr/At1DURtbHio3c9JKwBoI8EbU4clUqHTPGiWzDZ0CIQDGlkFqLTR+GKNCeIXf2amWUXbN
2020-10-20 09:57:42.066 4810-4827/com.calvin.android.sample I/System.out: Biq5VLDGRx20+WIL8wIhAL0Y6U8Kr/DRtD6k5r9OfJxSMyr4WNV0bM+z2VPbUoCdAiEArnqj3NL8
2020-10-20 09:57:42.066 4810-4827/com.calvin.android.sample I/System.out: 9PFWt/dGwIfwXZcTx01sykrjykH/ktstzwsCIQDETuncItM2NW3ol+G0woBElkaPrdANYhmWjOG9
2020-10-20 09:57:42.066 4810-4827/com.calvin.android.sample I/System.out: FOG4Lw==
2020-10-20 09:57:42.067 4810-4827/com.calvin.android.sample I/System.out:  ----私钥加密--公钥解密----
2020-10-20 09:57:42.067 4810-4827/com.calvin.android.sample I/System.out: 原文:
2020-10-20 09:57:42.067 4810-4827/com.calvin.android.sample I/System.out:  RSA加密算法
2020-10-20 09:57:42.071 4810-4827/com.calvin.android.sample I/System.out: 加密后:
2020-10-20 09:57:42.071 4810-4827/com.calvin.android.sample I/System.out:  pOqsIefLKzH55AytuUzbxoTj9xpYdDfIqCHAF7f+/9KCEti/qMI4gc3Xbz7NWy7Y9qQxLKCBv9QU
2020-10-20 09:57:42.071 4810-4827/com.calvin.android.sample I/System.out: rmYcnyJ61A==
2020-10-20 09:57:42.072 4810-4827/com.calvin.android.sample I/System.out: 解密后:
2020-10-20 09:57:42.072 4810-4827/com.calvin.android.sample I/System.out:  RSA加密算法
2020-10-20 09:57:42.072 4810-4827/com.calvin.android.sample I/System.out:  ----公钥加密--私钥解密----
2020-10-20 09:57:42.072 4810-4827/com.calvin.android.sample I/System.out: 原文:
2020-10-20 09:57:42.072 4810-4827/com.calvin.android.sample I/System.out:  RSA Encrypt Algorithm
2020-10-20 09:57:42.073 4810-4827/com.calvin.android.sample I/System.out: 加密后:
2020-10-20 09:57:42.073 4810-4827/com.calvin.android.sample I/System.out:  IQovrNhy9tcV8BzT7kxeuACfh+wFkhUWjVHbJBsduGDZUmIygzJVNFQMeMj0pKNUIJilNOyvWjGs
2020-10-20 09:57:42.074 4810-4827/com.calvin.android.sample I/System.out: Q9sOAdEiWw==
2020-10-20 09:57:42.075 4810-4827/com.calvin.android.sample I/System.out: 解密后:
2020-10-20 09:57:42.075 4810-4827/com.calvin.android.sample I/System.out:  RSA Encrypt Algorithm

4. 算法实现分析

RSA算法原理如下:

1.随机选择两个大质数p和q,p不等于q,计算N=pq;
2.选择一个大于1小于N的自然数e,e必须与(p-1)(q-1)互素。
3.用公式计算出d:d×e = 1 (mod (p-1)(q-1)) 。
4.销毁p和q。

最终得到的N和e就是“公钥”,d就是“私钥”,发送方使用N去加密数据,接收方只有使用d才能解开数据内容。

RSA的安全性依赖于大数分解,小于1024位的N已经被证明是不安全的,而且由于RSA算法进行的都是大数计算,使得RSA最快的情况也比DES慢上倍,这是RSA最大的缺陷,因此通常只能用于加密少量数据或者加密密钥,但RSA仍然不失为一种高强度的算法。

5. 数据分段处理

关于加密填充方式:之前以为上面这些操作就能实现rsa加解密,以为万事大吉了,呵呵,这事还没完,悲剧还是发生了,Android这边加密过的数据,服务器端死活解密不了,原来android系统的RSA实现是"RSA/None/NoPadding",而标准JDK实现是"RSA/None/PKCS1Padding" ,这造成了在android机上加密后无法在服务器上解密的原因,所以在实现的时候这个一定要注意。

public static final String RSA = "RSA";// 非对称加密密钥算法
public static final String ECB_PKCS1_PADDING = "RSA/ECB/PKCS1Padding";//加密填充方式

实现分段加密:搞定了填充方式之后又自信的认为万事大吉了,可是意外还是发生了,RSA非对称加密内容长度有限制,1024位key的最多只能加密127位数据,否则就会报错(javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes) , RSA 是常用的非对称加密算法。最近使用时却出现了“不正确的长度”的异常,研究发现是由于待加密的数据超长所致。RSA 算法规定:待加密的字节数不能超过密钥的长度值除以 8 再减去 11(即:KeySize / 8 - 11),而加密后得到密文的字节数,正好是密钥的长度值除以 8(即:KeySize / 8)。

public static final int DEFAULT_KEY_SIZE = 2048;//秘钥默认长度public static final byte[] DEFAULT_SPLIT = "#PART#".getBytes();    // 当要加密的内容超过bufferSize,则采用partSplit进行分块加密public static final int DEFAULT_BUFFERSIZE = (DEFAULT_KEY_SIZE / 8) - 11;// 当前秘钥支持加密的最大字节数

公钥分段加密

/*** 用公钥对字符串进行分段加密**/public static byte[] encryptByPublicKeyForSpilt(byte[] data, byte[] publicKey) throws Exception {int dataLen = data.length;if (dataLen <= DEFAULT_BUFFERSIZE) {return encryptByPublicKey(data, publicKey);}List<Byte> allBytes = new ArrayList<Byte>(2048);int bufIndex = 0;int subDataLoop = 0;byte[] buf = new byte[DEFAULT_BUFFERSIZE];for (int i = 0; i < dataLen; i++) {buf[bufIndex] = data[i];if (++bufIndex == DEFAULT_BUFFERSIZE || i == dataLen - 1) {subDataLoop++;if (subDataLoop != 1) {for (byte b : DEFAULT_SPLIT) {allBytes.add(b);}}byte[] encryptBytes = encryptByPublicKey(buf, publicKey);for (byte b : encryptBytes) {allBytes.add(b);}bufIndex = 0;if (i == dataLen - 1) {buf = null;} else {buf = new byte[Math.min(DEFAULT_BUFFERSIZE, dataLen - i - 1)];}}}byte[] bytes = new byte[allBytes.size()];{int i = 0;for (Byte b : allBytes) {bytes[i++] = b.byteValue();}}return bytes;}

私钥分段加密

 /*** 分段加密** @param data       要加密的原始数据* @param privateKey 秘钥*/public static byte[] encryptByPrivateKeyForSpilt(byte[] data, byte[] privateKey) throws Exception {int dataLen = data.length;if (dataLen <= DEFAULT_BUFFERSIZE) {return encryptByPrivateKey(data, privateKey);}List<Byte> allBytes = new ArrayList<Byte>(2048);int bufIndex = 0;int subDataLoop = 0;byte[] buf = new byte[DEFAULT_BUFFERSIZE];for (int i = 0; i < dataLen; i++) {buf[bufIndex] = data[i];if (++bufIndex == DEFAULT_BUFFERSIZE || i == dataLen - 1) {subDataLoop++;if (subDataLoop != 1) {for (byte b : DEFAULT_SPLIT) {allBytes.add(b);}}byte[] encryptBytes = encryptByPrivateKey(buf, privateKey);for (byte b : encryptBytes) {allBytes.add(b);}bufIndex = 0;if (i == dataLen - 1) {buf = null;} else {buf = new byte[Math.min(DEFAULT_BUFFERSIZE, dataLen - i - 1)];}}}byte[] bytes = new byte[allBytes.size()];{int i = 0;for (Byte b : allBytes) {bytes[i++] = b.byteValue();}}return bytes;}

公钥分段解密

/*** 公钥分段解密** @param encrypted 待解密数据* @param publicKey 密钥*/public static byte[] decryptByPublicKeyForSpilt(byte[] encrypted, byte[] publicKey) throws Exception {int splitLen = DEFAULT_SPLIT.length;if (splitLen <= 0) {return decryptByPublicKey(encrypted, publicKey);}int dataLen = encrypted.length;List<Byte> allBytes = new ArrayList<Byte>(1024);int latestStartIndex = 0;for (int i = 0; i < dataLen; i++) {byte bt = encrypted[i];boolean isMatchSplit = false;if (i == dataLen - 1) {// 到data的最后了byte[] part = new byte[dataLen - latestStartIndex];System.arraycopy(encrypted, latestStartIndex, part, 0, part.length);byte[] decryptPart = decryptByPublicKey(part, publicKey);for (byte b : decryptPart) {allBytes.add(b);}latestStartIndex = i + splitLen;i = latestStartIndex - 1;} else if (bt == DEFAULT_SPLIT[0]) {// 这个是以split[0]开头if (splitLen > 1) {if (i + splitLen < dataLen) {// 没有超出data的范围for (int j = 1; j < splitLen; j++) {if (DEFAULT_SPLIT[j] != encrypted[i + j]) {break;}if (j == splitLen - 1) {// 验证到split的最后一位,都没有break,则表明已经确认是split段isMatchSplit = true;}}}} else {// split只有一位,则已经匹配了isMatchSplit = true;}}if (isMatchSplit) {byte[] part = new byte[i - latestStartIndex];System.arraycopy(encrypted, latestStartIndex, part, 0, part.length);byte[] decryptPart = decryptByPublicKey(part, publicKey);for (byte b : decryptPart) {allBytes.add(b);}latestStartIndex = i + splitLen;i = latestStartIndex - 1;}}byte[] bytes = new byte[allBytes.size()];{int i = 0;for (Byte b : allBytes) {bytes[i++] = b.byteValue();}}return bytes;}

私钥分段解密

/*** 使用私钥分段解密**/public static byte[] decryptByPrivateKeyForSpilt(byte[] encrypted, byte[] privateKey) throws Exception {int splitLen = DEFAULT_SPLIT.length;if (splitLen <= 0) {return decryptByPrivateKey(encrypted, privateKey);}int dataLen = encrypted.length;List<Byte> allBytes = new ArrayList<Byte>(1024);int latestStartIndex = 0;for (int i = 0; i < dataLen; i++) {byte bt = encrypted[i];boolean isMatchSplit = false;if (i == dataLen - 1) {// 到data的最后了byte[] part = new byte[dataLen - latestStartIndex];System.arraycopy(encrypted, latestStartIndex, part, 0, part.length);byte[] decryptPart = decryptByPrivateKey(part, privateKey);for (byte b : decryptPart) {allBytes.add(b);}latestStartIndex = i + splitLen;i = latestStartIndex - 1;} else if (bt == DEFAULT_SPLIT[0]) {// 这个是以split[0]开头if (splitLen > 1) {if (i + splitLen < dataLen) {// 没有超出data的范围for (int j = 1; j < splitLen; j++) {if (DEFAULT_SPLIT[j] != encrypted[i + j]) {break;}if (j == splitLen - 1) {// 验证到split的最后一位,都没有break,则表明已经确认是split段isMatchSplit = true;}}}} else {// split只有一位,则已经匹配了isMatchSplit = true;}}if (isMatchSplit) {byte[] part = new byte[i - latestStartIndex];System.arraycopy(encrypted, latestStartIndex, part, 0, part.length);byte[] decryptPart = decryptByPrivateKey(part, privateKey);for (byte b : decryptPart) {allBytes.add(b);}latestStartIndex = i + splitLen;i = latestStartIndex - 1;}}byte[] bytes = new byte[allBytes.size()];{int i = 0;for (Byte b : allBytes) {bytes[i++] = b.byteValue();}}return bytes;}

这样总算把遇见的问题解决了,项目中使用的方案是客户端公钥加密,服务器私钥解密,服务器开发人员说是出于效率考虑,所以还是自己写了个程序测试一下真正的效率

第一步:准备100条对象数据

List<Person> personList=new ArrayList<>();int testMaxCount=100;//测试的最大数据条数//添加测试数据for(int i=0;i<testMaxCount;i++){Person person =new Person();person.setAge(i);person.setName(String.valueOf(i));personList.add(person);}//FastJson生成json数据String jsonData=JsonUtils.objectToJsonForFastJson(personList);Log.e("MainActivity","加密前json数据 ---->"+jsonData);Log.e("MainActivity","加密前json数据长度 ---->"+jsonData.length());

第二步生成秘钥对

KeyPair keyPair=RSAUtils.generateRSAKeyPair(RSAUtils.DEFAULT_KEY_SIZE);// 公钥RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();// 私钥RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

接下来分别使用公钥加密 私钥解密 私钥加密 公钥解密

//公钥加密long start=System.currentTimeMillis();byte[] encryptBytes=    RSAUtils.encryptByPublicKeyForSpilt(jsonData.getBytes(),publicKey.getEncoded());long end=System.currentTimeMillis();Log.e("MainActivity","公钥加密耗时 cost time---->"+(end-start));String encryStr=Base64Encoder.encode(encryptBytes);Log.e("MainActivity","加密后json数据 --1-->"+encryStr);Log.e("MainActivity","加密后json数据长度 --1-->"+encryStr.length());//私钥解密start=System.currentTimeMillis();byte[] decryptBytes=  RSAUtils.decryptByPrivateKeyForSpilt(Base64Decoder.decodeToBytes(encryStr),privateKey.getEncoded());String decryStr=new String(decryptBytes);end=System.currentTimeMillis();Log.e("MainActivity","私钥解密耗时 cost time---->"+(end-start));Log.e("MainActivity","解密后json数据 --1-->"+decryStr);//私钥加密start=System.currentTimeMillis();encryptBytes=    RSAUtils.encryptByPrivateKeyForSpilt(jsonData.getBytes(),privateKey.getEncoded());end=System.currentTimeMillis();Log.e("MainActivity","私钥加密密耗时 cost time---->"+(end-start));encryStr=Base64Encoder.encode(encryptBytes);Log.e("MainActivity","加密后json数据 --2-->"+encryStr);Log.e("MainActivity","加密后json数据长度 --2-->"+encryStr.length());//公钥解密start=System.currentTimeMillis();decryptBytes=  RSAUtils.decryptByPublicKeyForSpilt(Base64Decoder.decodeToBytes(encryStr),publicKey.getEncoded());decryStr=new String(decryptBytes);end=System.currentTimeMillis();Log.e("MainActivity","公钥解密耗时 cost time---->"+(end-start));Log.e("MainActivity","解密后json数据 --2-->"+decryStr);

运行结果:

对比发现:私钥的加解密都很耗时,所以可以根据不同的需求采用不能方案来进行加解密。个人觉得服务器要求解密效率高,客户端私钥加密,服务器公钥解密比较好一点

加密后数据大小的变化:数据量差不多是加密前的1.5倍

非对称加密之RSA算法相关推荐

  1. JackHttp -- 浅谈编码、加密(对称加密,非对称加密,Hash算法)

    如果你还不清楚 JackHttp 是什么,请戳这里!!! JackHttp 是一个网络框架系列,为什么还要分享编码和加密呢?主要有如下几个原因: HTTP 在网络传输过程中是明文的. HTTP 在网络 ...

  2. RSA算法原理简介,非对称加密,公开密钥算法(易懂篇)

    RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它.但是有不少新来的同事对它不太了解,恰好看到一本书中作者用实例对它进行了简化而生动的描述,使得高深的数学理论能够被容易地理解.我们经 ...

  3. 非对称加密算法之RSA算法实现

    对称加密,非对称加密,公钥,私钥,RSA这些常常听到的,到底是怎么回事 有个同事问我公钥私钥到底为什么能互相解开,一时语塞,平时都只是知道怎么用,但很少去了解的更细,现在做个整理,记个笔记 非对称加密 ...

  4. 对称加密、非对称加密、RSA、消息摘要、数字签名、数字证书与 HTTPS 简介

    文章目录 1.加密算法简介 1.1 对称加密(Symmetric Key Algorithms) 1.2 非对称加密(Asymmetric Key Algorithms) 1.3 非对称加密 RSA ...

  5. 非对称加密下RSA在Java的简明教程

    引言 在现实世界中,每个人都有自己的密码.在各种系统中都有各类加密和解密的需求. 本文将详细介绍一下RSA的前身后世,应用场景和在Java中的实现,从理论到实践,一步到位,触手可用. 非对称加密与对称 ...

  6. 图文结合彻底理解非对称加密、RSA原理及安全性(图文版)

    博主:爱码叔 个人博客站点: icodebook 公众号:漫话软件设计 专注于软件设计与架构.技术管理.擅长用通俗易懂的语言讲解技术.对技术管理工作有自己的一定见解.文章会第一时间首发在个站上,欢迎大 ...

  7. 经典非对称加密算法:RSA算法原理、实现详解(C++、Java)

    目录 零.写在最前 参数说明 一.RSA算法原理介绍 二.实验步骤(含实验方法与关键代码) 1. 创建项目 2. 设计加密.解密的总体流程 3. 设计素数类PrimeNum,包括两个静态方法 4. 设 ...

  8. PHP非对称加密:RSA (RSA/ECB/PKCS1Padding)+base64_encode/bin2hex加密

    所谓非对称,就是使用公钥/私钥加密,然后用对应的私钥/公钥解密 1.配对的公钥,私钥: //公钥(注意包括头(-----BEGIN PUBLIC KEY-----)尾(-----END PUBLIC ...

  9. 在线加密解密网站(对称加密:AES、DES、RC,非对称加密:RSA)

    前两天写AES加密相关代码,学习的同时找到一个在线加密解密的网站,帮助自己快速理解了一下,推荐给学习加密的同学.在线加密网站,一开始接触加密(AES等)可以在这里体验下加密与解密,助于快速理解加密模式 ...

最新文章

  1. Spring父子容器的关系分析--用实例说话
  2. 基于python的快速傅里叶变换FFT(二)
  3. ValueError: Must have equal len keys and value when setting with an iterable
  4. apt-get update 出现E: Could not get lock /var/lib/apt/lists/lock问题的解决
  5. sql获取oracle数据库数据,通过sql语句获取数据库的基本信息
  6. 每天一道LeetCode-----实现LFU置换算法
  7. OpenStack 的部署T版(二)——Keystone组件
  8. 用vi在linux下查看16进制文件
  9. 前端开发自学之JavaScript——显示当前时间
  10. MongoDB基础使用
  11. 利用正则表达式提取网页中Table内的数据
  12. [Linux网络编程]ARP简单实例
  13. html登录页面的校验控件,HTML5一款有趣智能的密码输入界面控件
  14. 第12章类和动态内存分配
  15. python的sqlite3说明_python之sqlite3使用详解
  16. 很迷茫,30岁,大专学历,没有一技之长,负债累累,怎么翻身?
  17. 用了一个多月时间治好了自己的胸膜炎
  18. 使用dos删除隐藏的.git文件
  19. linux Ubuntu 报错:No command ‘setenv‘ found
  20. 最新uboot的Kbuild系统 3 .config的生成

热门文章

  1. 如何做出高水准的竞品分析?(方法论+模板)
  2. 基于Web的系统测试方法(张友生(来自中国系统分析师/中国系统分析员))
  3. HOW2J j2se实战小项目-记事本项目
  4. matlab 灰度共生矩阵熵,结合灰度共生矩阵和熵的图像修复算法
  5. uniapp 封装导航栏
  6. java遍历map的几种方式
  7. 一款非常牛逼的Java爬虫框架(高度灵活可配置)
  8. 如何使用GoldWave合成音乐?
  9. VisualGDB导致Visual Studio报错:未能从程序集Package.LanguageService中加载类型xxx
  10. 【独家】彩虹代shua最新6.6版本/免授权/后台同步官方版本升级