非对称加密之RSA算法
非对称加密之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、2为密钥构建及发布流程。
- 构建加密消息传递
步骤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算法相关推荐
- JackHttp -- 浅谈编码、加密(对称加密,非对称加密,Hash算法)
如果你还不清楚 JackHttp 是什么,请戳这里!!! JackHttp 是一个网络框架系列,为什么还要分享编码和加密呢?主要有如下几个原因: HTTP 在网络传输过程中是明文的. HTTP 在网络 ...
- RSA算法原理简介,非对称加密,公开密钥算法(易懂篇)
RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它.但是有不少新来的同事对它不太了解,恰好看到一本书中作者用实例对它进行了简化而生动的描述,使得高深的数学理论能够被容易地理解.我们经 ...
- 非对称加密算法之RSA算法实现
对称加密,非对称加密,公钥,私钥,RSA这些常常听到的,到底是怎么回事 有个同事问我公钥私钥到底为什么能互相解开,一时语塞,平时都只是知道怎么用,但很少去了解的更细,现在做个整理,记个笔记 非对称加密 ...
- 对称加密、非对称加密、RSA、消息摘要、数字签名、数字证书与 HTTPS 简介
文章目录 1.加密算法简介 1.1 对称加密(Symmetric Key Algorithms) 1.2 非对称加密(Asymmetric Key Algorithms) 1.3 非对称加密 RSA ...
- 非对称加密下RSA在Java的简明教程
引言 在现实世界中,每个人都有自己的密码.在各种系统中都有各类加密和解密的需求. 本文将详细介绍一下RSA的前身后世,应用场景和在Java中的实现,从理论到实践,一步到位,触手可用. 非对称加密与对称 ...
- 图文结合彻底理解非对称加密、RSA原理及安全性(图文版)
博主:爱码叔 个人博客站点: icodebook 公众号:漫话软件设计 专注于软件设计与架构.技术管理.擅长用通俗易懂的语言讲解技术.对技术管理工作有自己的一定见解.文章会第一时间首发在个站上,欢迎大 ...
- 经典非对称加密算法:RSA算法原理、实现详解(C++、Java)
目录 零.写在最前 参数说明 一.RSA算法原理介绍 二.实验步骤(含实验方法与关键代码) 1. 创建项目 2. 设计加密.解密的总体流程 3. 设计素数类PrimeNum,包括两个静态方法 4. 设 ...
- PHP非对称加密:RSA (RSA/ECB/PKCS1Padding)+base64_encode/bin2hex加密
所谓非对称,就是使用公钥/私钥加密,然后用对应的私钥/公钥解密 1.配对的公钥,私钥: //公钥(注意包括头(-----BEGIN PUBLIC KEY-----)尾(-----END PUBLIC ...
- 在线加密解密网站(对称加密:AES、DES、RC,非对称加密:RSA)
前两天写AES加密相关代码,学习的同时找到一个在线加密解密的网站,帮助自己快速理解了一下,推荐给学习加密的同学.在线加密网站,一开始接触加密(AES等)可以在这里体验下加密与解密,助于快速理解加密模式 ...
最新文章
- Spring父子容器的关系分析--用实例说话
- 基于python的快速傅里叶变换FFT(二)
- ValueError: Must have equal len keys and value when setting with an iterable
- apt-get update 出现E: Could not get lock /var/lib/apt/lists/lock问题的解决
- sql获取oracle数据库数据,通过sql语句获取数据库的基本信息
- 每天一道LeetCode-----实现LFU置换算法
- OpenStack 的部署T版(二)——Keystone组件
- 用vi在linux下查看16进制文件
- 前端开发自学之JavaScript——显示当前时间
- MongoDB基础使用
- 利用正则表达式提取网页中Table内的数据
- [Linux网络编程]ARP简单实例
- html登录页面的校验控件,HTML5一款有趣智能的密码输入界面控件
- 第12章类和动态内存分配
- python的sqlite3说明_python之sqlite3使用详解
- 很迷茫,30岁,大专学历,没有一技之长,负债累累,怎么翻身?
- 用了一个多月时间治好了自己的胸膜炎
- 使用dos删除隐藏的.git文件
- linux Ubuntu 报错:No command ‘setenv‘ found
- 最新uboot的Kbuild系统 3 .config的生成
热门文章
- 如何做出高水准的竞品分析?(方法论+模板)
- 基于Web的系统测试方法(张友生(来自中国系统分析师/中国系统分析员))
- HOW2J j2se实战小项目-记事本项目
- matlab 灰度共生矩阵熵,结合灰度共生矩阵和熵的图像修复算法
- uniapp 封装导航栏
- java遍历map的几种方式
- 一款非常牛逼的Java爬虫框架(高度灵活可配置)
- 如何使用GoldWave合成音乐?
- VisualGDB导致Visual Studio报错:未能从程序集Package.LanguageService中加载类型xxx
- 【独家】彩虹代shua最新6.6版本/免授权/后台同步官方版本升级