Android(安卓)RSA 加密(分段加密)
16lz
2021-12-04
package com.dhh.easy.wahu.utils;import android.util.*;import android.util.Base64;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.ArrayList;import java.util.List;import javax.crypto.Cipher;/** * Created by Administrator on 2019/5/17 0017. */public class RSAAndroid { private static String TAG = "RSAAndroid"; public static final String RSA = "RSA";// 非对称加密密钥算法 public static final String ECB_PKCS1_PADDING = "RSA/ECB/PKCS1Padding";//加密填充方式 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;// 当前秘钥支持加密的最大字节数 /** * 随机生成RSA密钥对 * * @param keyLength 密钥长度,范围:512~2048 * 一般1024 * @return */ public static KeyPair generateRSAKeyPair(int keyLength) { try { KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA); kpg.initialize(keyLength); return kpg.genKeyPair(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } /** * 用公钥对字符串进行加密 * * @param data 原文 */ public static byte[] encryptByPublicKey(byte[] data, byte[] publicKey) throws Exception { // 得到公钥 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey); KeyFactory kf = KeyFactory.getInstance(RSA); PublicKey keyPublic = kf.generatePublic(keySpec); // 加密数据 Cipher cp = Cipher.getInstance(ECB_PKCS1_PADDING); cp.init(Cipher.ENCRYPT_MODE, keyPublic); return cp.doFinal(data); } /** * 私钥加密 * * @param data 待加密数据 * @param privateKey 密钥 * @return byte[] 加密数据 */ public static byte[] encryptByPrivateKey(byte[] data, byte[] privateKey) throws Exception { // 得到私钥 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey); KeyFactory kf = KeyFactory.getInstance(RSA); PrivateKey keyPrivate = kf.generatePrivate(keySpec); // 数据加密 Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING); cipher.init(Cipher.ENCRYPT_MODE, keyPrivate); return cipher.doFinal(data); } /** * 公钥解密 * * @param data 待解密数据 * @param publicKey 密钥 * @return byte[] 解密数据 */ public static byte[] decryptByPublicKey(byte[] data, byte[] publicKey) throws Exception { // 得到公钥 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey); KeyFactory kf = KeyFactory.getInstance(RSA); PublicKey keyPublic = kf.generatePublic(keySpec); // 数据解密 Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING); cipher.init(Cipher.DECRYPT_MODE, keyPublic); return cipher.doFinal(data); } /** * 使用私钥进行解密 */ public static byte[] decryptByPrivateKey(byte[] encrypted, byte[] privateKey) throws Exception { // 得到私钥 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey); KeyFactory kf = KeyFactory.getInstance(RSA); PrivateKey keyPrivate = kf.generatePrivate(keySpec); // 解密数据 Cipher cp = Cipher.getInstance(ECB_PKCS1_PADDING); cp.init(Cipher.DECRYPT_MODE, keyPrivate); byte[] arr = cp.doFinal(encrypted); return arr; } /** * 用公钥对字符串进行分段加密 * */ public static byte[] encryptByPublicKeyForSpilt(byte[] data, byte[] publicKey) throws Exception { int dataLen = data.length; if (dataLen <= DEFAULT_BUFFERSIZE) { return encryptByPublicKey(data, publicKey); } List allBytes = new ArrayList(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 allBytes = new ArrayList(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 allBytes = new ArrayList(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 allBytes = new ArrayList(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; } public static void testEncrypt(String content) { //生成秘钥对 KeyPair keyPair = RSAAndroid.generateRSAKeyPair(RSAAndroid.DEFAULT_KEY_SIZE); //公钥 PublicKey publicKey = keyPair.getPublic(); //私钥 PrivateKey privateKey = keyPair.getPrivate(); long start; long end; byte[] encryptBytes = new byte[0]; byte[] decryptBytes = new byte[0]; String encryStr, decryStr; try { //公钥加密 start = System.currentTimeMillis(); encryptBytes = RSAAndroid.encryptByPublicKeyForSpilt(content.getBytes(), publicKey.getEncoded()); Log.i(TAG, "testEncrypt: 公钥加密 encryptBytes:"+encryptBytes); end = System.currentTimeMillis(); Log.e(TAG, "公钥加密耗时 cost time---->" + (end - start)); //encryStr = BASE64Encoder.encode(encryptBytes); encryStr = android.util.Base64.encodeToString(encryptBytes, Base64.DEFAULT);// Log.e(TAG, "加密后json数据 --1-->" + encryStr); Log.e(TAG, "加密后json数据长度 --1-->" + encryStr.length()); Log.i(TAG, "testEncrypt: encryStr:"+encryStr); //私钥解密 start = System.currentTimeMillis(); decryptBytes = RSAAndroid.decryptByPrivateKeyForSpilt(Base64.decode(encryStr,Base64.DEFAULT), privateKey.getEncoded()); decryStr = new String(decryptBytes); Log.i(TAG, "testEncrypt: 私钥解密 decryStr:"+decryStr); end = System.currentTimeMillis(); Log.e(TAG, "私钥解密耗时 cost time---->" + (end - start)); Log.e(TAG, "解密后json数据 --1-->" + decryStr); } catch (Exception e) { e.printStackTrace(); } try { //私钥加密 start = System.currentTimeMillis(); encryptBytes = RSAAndroid.encryptByPrivateKeyForSpilt(content.getBytes(), privateKey.getEncoded()); end = System.currentTimeMillis(); Log.e(TAG, "私钥加密密耗时 cost time---->" + (end - start)); encryStr = android.util.Base64.encodeToString(encryptBytes, Base64.DEFAULT);// Log.e(TAG, "加密后json数据 --2-->" + encryStr); Log.e(TAG, "加密后json数据长度 --2-->" + encryStr.length()); Log.i(TAG, "testEncrypt: 私钥加密密 encryStr:"+encryStr); //公钥解密 start = System.currentTimeMillis(); decryptBytes = RSAAndroid.decryptByPublicKeyForSpilt(Base64.decode(encryStr,Base64.DEFAULT), publicKey.getEncoded()); decryStr = new String(decryptBytes); Log.i(TAG, "testEncrypt: 公钥解密 decryStr:"+decryStr); end = System.currentTimeMillis(); Log.e(TAG, "公钥解密耗时 cost time---->" + (end - start)); Log.e(TAG, "解密后json数据 --2-->" + decryStr); } catch (Exception e) { e.printStackTrace(); } }}
Android 数据加密之Rsa加密 https://blog.csdn.net/qq_26057629/article/details/81776133
https://blog.csdn.net/fugang1230/article/details/79379490
RSA 解密的时候报错 而且有乱码:java.lang.ArrayIndexOutOfBoundsException: too much data for RSA block https://blog.csdn.net/Rodulf/article/details/50957311
too much data for RSA block .关于RSA算法密钥长度/密文长度/明文长度 https://blog.csdn.net/centralperk/article/details/8553759
https://blog.csdn.net/qqxiaoqiang1573/article/details/51253808 Base64 加密解密字符串的简单使用
https://www.cnblogs.com/zhujiabin/p/7877777.html
//import android.util.Base64; String str = "Hello!"; //base64编码 //String strBase64 = new String(Base64.encode(str.getBytes(), Base64.DEFAULT)); String strBase64 = Base64.encodeToString(str.getBytes(), Base64.DEFAULT); //base64解码 String str2 = new String(Base64.decode(strBase64.getBytes(), Base64.DEFAULT));
更多相关文章
- JNI基本数据类型转换
- android:uploaddatatoWeb
- ch020 Android(安卓)SQLite3(第一部分)
- Android:SQLiteOpenHelper
- ch020 Android(安卓)SQLite3(第一部分)
- Android(安卓)Jetpack 之 LiveData
- Android实现DES对字符串加密
- Android摄像头视频帧数据测试代码
- Android使用HttpURLConnection上传文件