目录介绍
-
1.加密和解密
- 1.1 问答环节
- 1.2 加解密概况
-
2.对称加密和非对称加密
- 2.1 什么是对称加密
- 2.2 什么是非对称加密
- 2.3 常见对称加密有什么
- 2.4 常见非对称加密有什么
- 2.5 非对称加密用途
-
3.关于单向加密
- 3.1 MD加密
- 3.2 什么叫做加盐
-
4.加密和解密代码展示
- 4.1 DES加密和解密
- 4.2 AES解密和解密
-
5.RSA非对称加解密
- 5.1 公钥加密,私钥解密
- 5.2 私钥加密,公钥解密
- 5.3 完整工具类代码
- 5.4 注意RSA加密填充方式
- 5.5 RSA加密内容长度限制问题
- 5.6 加解密效率测试
- 5.7 分段加密解密工具类代码
好消息
- 博客笔记大汇总【16年3月到至今】,包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!转载请注明出处,谢谢!
- https://github.com/yangchong2...
1.加密和解密
1.1 问答环节
- 1.1.1 常见的加密和解密有哪些?
- 1.1.2 MD5加密是属于什么类型?是否可逆,以及有哪些应用场景?
- 1.1.3 实际开发中有哪些加解密的应用场景?
1.2 加解密概况
- 1)在对称加密算法中,双方使用的密钥相同,要求解密方事先必须知道加密密钥。这类加密算法技术较为成熟,加密效率高。
- 2)在非对称加密算法中,收发双方使用不同的密钥,发方使用公开密钥对消息进行加密,收发使用私有密钥机型解密,保密性更高,但效率更低。
- 3)单向加密算法在加密过程中不需要使用密钥,输入明文后由算法直接加密成密文,密文无法解密,只有重新输入密文,并经过同样的加密算法处理,得到形同的密文并被系统重新识别后,才能真正的解密,这种算法非常复杂,通常只在数据量有限的情形下使用,如广泛应用在计算机系统中的口令加密等。
2.对称加密和非对称加密
2.1 什么是对称加密
- 密钥可以自己指定,只有一把密钥,如果密钥暴露,文件就会被暴露
- 特点是加密速度很快,但是缺点是安全性较低,因为只要密钥暴漏,数据就可以被解密了。
- 一句话概括:加密和解密都是用相同密钥
2.2 什么是非对称加密
- 有两把钥匙(密钥对),公钥和私钥,公钥的话给别人,私钥自己保存
- 把密钥通常是通过程序生成,不能自己指定
- 特点是加密速度慢些,但是安全系数很高
- 加密和解密的规则是:公钥加密只能私钥解密,私钥加密只能公钥解密
- 应用场景举例:在集成支付宝支付sdk时,需要生成私钥和公钥,公钥需要设置到支付宝网站的管理后台,在程序中调用支付接口的时候,使用我们自己的私钥进行加密,这样支付宝由于有公钥可以解密,其他人即时劫持了数据,但是没有公钥,也无法解密。
2.3 常见对称加密有什么
- DES算法(Data Encryption Standard)
- AES算法(Advanced Encryption Standard)
2.4 常见非对称加密有什么
- RSA
2.5 非对称加密用途
-
身份认证
- 一条加密信息若能用A 的公钥能解开,则该信息一定是用A 的私钥加密的,该能确定该用户是A。
-
陌生人通信
- A 和B 两个人互不认识,A把自己的公钥发给B,B也把自己的公钥发给A,则双方可以通过对方的公钥加密信息通信。C 虽然也能得到A、B 的公钥,但是他解不开密文。
-
支付宝支付加密
- 具体可以参考支付宝sdk的官方demo
3.关于单向加密
-
MD5
- 关于MD5加密的工具类代码如下所示
4.加密和解密代码展示
4.1 DES加密和解密【对称加密】
-
加密过程
- 需要加密的内容,也就是明文;然后需要密钥。最后通过工具类加密得到加密后的密文
private final String desEncryptString = "yangchong"; private final String desEncryptKey = "19930311"; s1 = DES.encryptDES(desEncryptString, desEncryptKey); Log.e("加密和解密", s1); 加密和解密: 84r1gS+D3Op8yrSnF5ZDrQ== //s1为加密后的密文
-
解密过程
- 利用加密后的密文,与设置的key,也就是密钥,则可以解密得到加密的内容
String s2 = DES.decryptDES(s1, desEncryptKey); Log.e("加密和解密", s2); //加密和解密: yangchong
- Android中实现DES加密和解密的核心代码如下
public class DES {
//初始化向量,随意填写
private static byte[] iv = {1,2,3,4,5,6,7,8};
/**
*
* @param encryptString 明文
* @param encryptKey 密钥
* @return 加密后的密文
*/
public static String encryptDES(String encryptString,String encryptKey){
try {
//实例化IvParameterSpec对象,使用指定的初始化向量
IvParameterSpec zeroIv=new IvParameterSpec(iv);
//实例化SecretKeySpec,根据传入的密钥获得字节数组来构造SecretKeySpec
SecretKeySpec key =new SecretKeySpec(encryptKey.getBytes(),"DES");
//创建密码器
Cipher cipher=Cipher.getInstance("DES/CBC/PKCS5Padding");
//用密钥初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE,key,zeroIv);
//执行加密操作
byte[]encryptedData=cipher.doFinal(encryptString.getBytes());
return Base64.encodeToString(encryptedData,0);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}
/**
* 解密的过程与加密的过程大致相同
* @param decryptString 密文
* @param decryptKey 密钥
* @return 返回明文
*/
public static String decryptDES(String decryptString,String decryptKey){
try {
//先使用Base64解密
byte[]byteMi = Base64.decode(decryptString,0);
//实例化IvParameterSpec对象使用指定的初始化向量
IvParameterSpec zeroIv=new IvParameterSpec(iv);
//实例化SecretKeySpec,根据传入的密钥获得字节数组来构造SecretKeySpec,
SecretKeySpec key=new SecretKeySpec(decryptKey.getBytes(),"DES");
//创建密码器
Cipher cipher=Cipher.getInstance("DES/CBC/PKCS5Padding");
//用密钥初始化Cipher对象,上面是加密,这是解密模式
cipher.init(Cipher.DECRYPT_MODE,key,zeroIv);
//获取解密后的数据
byte [] decryptedData=cipher.doFinal(byteMi);
return new String(decryptedData);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}
}
4.2 AES解密和解密【对称加密】
public class AES {
private static final String Algorithm = "AES";
private final static String HEX = "0123456789ABCDEF";
//加密函数,key为密钥
public static String encrypt(String key, String src) throws Exception {
byte[] rawKey = getRawKey(key.getBytes());
byte[] result = encrypt(rawKey, src.getBytes());
return toHex(result);
}
//解密函数。key值必须和加密时的key一致
public static String decrypt(String key, String encrypted) throws Exception {
byte[] rawKey = getRawKey(key.getBytes());
byte[] enc = toByte(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance(Algorithm);
// SHA1PRNG 强随机种子算法, 要区别Android 4.2.2以上版本的调用方法
SecureRandom sr = null;
if (android.os.Build.VERSION.SDK_INT >= 17) {
sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
} else {
sr = SecureRandom.getInstance("SHA1PRNG");
}
sr.setSeed(seed);
kgen.init(256, sr); // 256位或128位或192位
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] encrypt(byte[] key, byte[] src) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(key, Algorithm);
Cipher cipher = Cipher.getInstance(Algorithm);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(src);
return encrypted;
}
private static byte[] decrypt(byte[] key, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(key, Algorithm);
Cipher cipher = Cipher.getInstance(Algorithm);
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
private static byte[] toByte(String hexString) {
int len = hexString.length() / 2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++) {
result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
}
return result;
}
private static String toHex(byte[] buf) {
if (buf == null) {
return "";
}
StringBuffer result = new StringBuffer(2 * buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
}
5.RSA非对称加解密
5.1 公钥加密,私钥解密
-
第一步:获取随机的公钥和私钥
- 代码如下所示:
//秘钥默认长度 public static final int DEFAULT_KEY_SIZE = 2048; KeyPair keyPair = RSA.generateRSAKeyPair(DEFAULT_KEY_SIZE); if (keyPair != null) { // 公钥 publicKey = (RSAPublicKey) keyPair.getPublic(); // 私钥 privateKey = (RSAPrivateKey) keyPair.getPrivate(); }
-
第二步:公钥加密
- 代码如下所示:
//用公钥对字符串进行加密 try { bytes = RSA.encryptByPublicKey(DEFAULT_SPLIT, publicKey.getEncoded()); String s = new String(bytes); Log.e("加密和解密", s); } catch (Exception e) { e.printStackTrace(); }
-
第三步:私钥解密
//使用私钥进行解密 try { byte[] bytes = RSA.decryptByPrivateKey(this.bytes, privateKey.getEncoded()); String s = new String(bytes); Log.e("加密和解密", s); //解密后得到的数据:yangchong } catch (Exception e) { e.printStackTrace(); }
5.2 私钥加密,公钥解密
-
第一步:获取随机的公钥和私钥
- 代码如下所示:
//秘钥默认长度 public static final int DEFAULT_KEY_SIZE = 2048; KeyPair keyPair = RSA.generateRSAKeyPair(DEFAULT_KEY_SIZE); if (keyPair != null) { // 公钥 publicKey = (RSAPublicKey) keyPair.getPublic(); // 私钥 privateKey = (RSAPrivateKey) keyPair.getPrivate(); }
-
第二步:私钥加密
- 代码如下所示:
//使用私钥加密 try { bytes1 = RSA.encryptByPrivateKey(DEFAULT_SPLIT, privateKey.getEncoded()); String s = new String(bytes); Log.e("加密和解密", s); } catch (Exception e) { e.printStackTrace(); }
-
第三步:公钥解密
//使用公钥解密 try { byte[] bytes = RSA.decryptByPublicKey(this.bytes1, publicKey.getEncoded()); String s = new String(bytes); Log.e("加密和解密", s); //解密后得到的数据:yangchong } catch (Exception e) { e.printStackTrace(); }
5.3 完整工具类代码
-
代码如下所示:
public class RSA { public static final String RSA = "RSA";// 非对称加密密钥算法 public static final String ECB_PKCS1_PADDING = "RSA/ECB/PKCS1Padding";//加密填充方式 /**
*
* @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 原文
* @param publicKey 密钥
* @return byte[] 解密数据
*/
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);
}
/**
* 使用私钥进行解密
* @param encrypted 待解密数据
* @param privateKey 密钥
* @return byte[] 解密数据
* @throws Exception 异常
*/
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;
}
}
```
5.4 注意RSA加密填充方式
- 之前以为上面操作就能实现rsa加解密,以为可以呢,但是遇到Android这边加密过的数据,服务器端死活解密不了,原来android系统的RSA实现是"RSA/None/NoPadding",而标准JDK实现是"RSA/None/PKCS1Padding",这造成了在android机上加密后无法在服务器上解密的原因,所以在实现的时候这个一定要注意这个问题。
5.5 RSA加密内容长度限制问题
- RSA非对称加密内容长度有限制,1024位key的最多只能加密127位数据,否则就会报错(javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes)
- RSA 算法规定:待加密的字节数不能超过密钥的长度值除以 8 再减去 11(即:KeySize / 8 - 11),而加密后得到密文的字节数,正好是密钥的长度值除以 8(即:KeySize / 8)。
5.6 加解密效率测试
-
第一步:获取随机的公钥和私钥
- 代码如下所示:
//秘钥默认长度 public static final int DEFAULT_KEY_SIZE = 2048; KeyPair keyPair = RSA.generateRSAKeyPair(DEFAULT_KEY_SIZE); if (keyPair != null) { // 公钥 publicKey = (RSAPublicKey) keyPair.getPublic(); // 私钥 privateKey = (RSAPrivateKey) keyPair.getPrivate(); }
-
第二步:用公钥对对象进行加密
- 代码如下所示:
//用公钥对对象进行加密 YC yc = new YC(); yc.setAge(25); yc.setName("杨充"); StringBuilder stringBuilder = new StringBuilder(); for(int a=0 ; a<500 ; a++){ stringBuilder.append("都比小杨"+a); } yc.setInfo(stringBuilder.toString()); String string = yc.toString(); long start = System.currentTimeMillis(); encryptBytes = new byte[0]; try { encryptBytes = RSA.encryptByPublicKeyForSpilt(string.getBytes(),publicKey.getEncoded()); } catch (Exception e) { e.printStackTrace(); } long end=System.currentTimeMillis(); Log.e("YC","公钥加密耗时 cost time---->"+(end-start)); String encryStr = new String(encryptBytes); Log.e("YC","加密前数据长度 --1-->"+string.length()); Log.e("YC","加密后数据长度 --1-->"+encryStr.length());
-
第三步:使用私钥进行解密
//使用私钥进行解密 long start2 = System.currentTimeMillis(); byte[] decryptBytes= new byte[0]; try { decryptBytes = RSA.decryptByPrivateKeyForSpilt(encryptBytes,privateKey.getEncoded()); } catch (Exception e) { e.printStackTrace(); } String decryStr = new String(decryptBytes); long end2 =System.currentTimeMillis(); Log.e("YC","私钥解密耗时 cost time---->"+(end2-start2)); Log.e("YC","解密后数据 --1-->"+decryStr);
-
第四步:加密和解密效率比较
- 如下所示
- 加密后数据大小的变化:数据量差不多是加密前的1.6倍
- 经过几次测试可知,解密要比加密费时间多,所以一般建议在服务端做解密的逻辑操作
5.7 分段加密解密工具类代码
-
代码如下所示
//秘钥默认长度 private static final int DEFAULT_KEY_SIZE = 2048; // 当前秘钥支持加密的最大字节数 private static final int DEFAULT_BUFFER_SIZE = (DEFAULT_KEY_SIZE / 8) - 11; // 当要加密的内容超过bufferSize,则采用partSplit进行分块加密 private static final byte[] DEFAULT_SPLIT = "#PART#".getBytes(); /** * 用公钥对字符串进行分段加密 * @param data 需要加密数据 * @param publicKey 公钥 * @return byte[] 加密数据 * @throws Exception 异常
*/
public static byte[] encryptByPublicKeyForSpilt(byte[] data, byte[] publicKey) throws Exception {
int dataLen = data.length;
if (dataLen <= DEFAULT_BUFFER_SIZE) {
return encryptByPublicKey(data, publicKey);
}
List<Byte> allBytes = new ArrayList<>(2048);
int bufIndex = 0;
int subDataLoop = 0;
byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
for (int i = 0; i < dataLen; i++) {
if (buf != null) {
buf[bufIndex] = data[i];
}
if (++bufIndex == DEFAULT_BUFFER_SIZE || 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_BUFFER_SIZE, dataLen - i - 1)];
}
}
}
byte[] bytes = new byte[allBytes.size()];
int i = 0;
for (Byte b : allBytes) {
bytes[i++] = b;
}
return bytes;
}
/**
* 用秘钥对字符串进行分段加密
*
* @param data 要加密的原始数据
* @param privateKey 秘钥
* @return byte[] 加密数据
* @throws Exception 异常
* https://github.com/yangchong211
*/
public static byte[] encryptByPrivateKeyForSpilt(byte[] data, byte[] privateKey) throws Exception {
int dataLen = data.length;
if (dataLen <= DEFAULT_BUFFER_SIZE) {
return encryptByPrivateKey(data, privateKey);
}
List<Byte> allBytes = new ArrayList<Byte>(2048);
int bufIndex = 0;
int subDataLoop = 0;
byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
for (int i = 0; i < dataLen; i++) {
if (buf != null) {
buf[bufIndex] = data[i];
}
if (++bufIndex == DEFAULT_BUFFER_SIZE || 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_BUFFER_SIZE, dataLen - i - 1)];
}
}
}
byte[] bytes = new byte[allBytes.size()];
int i = 0;
for (Byte b : allBytes) {
bytes[i++] = b;
}
return bytes;
}
/**
* 用公钥分段解密
*
* @param encrypted 待解密数据
* @param publicKey 公钥
* @return byte[] 解密数据
* @throws Exception 异常
* https://github.com/yangchong211
*/
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;
}
return bytes;
}
/**
* 使用私钥分段解密
*
* @param encrypted 待解密数据
* @param privateKey 私钥
* @return byte[] 解密数据
* @throws Exception 异常
* https://github.com/yangchong211
*/
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;
}
return bytes;
}
```
关于其他内容介绍
01.关于博客汇总链接
02.关于我的博客
- 我的个人站点:www.yczbj.org,www.ycbjie.cn
- github:https://github.com/yangchong211
- 知乎:https://www.zhihu.com/people/...
- 简书:http://www.jianshu.com/u/b7b2...
- csdn:http://my.csdn.net/m0_37700275
- 喜马拉雅听书:http://www.ximalaya.com/zhubo...
- 开源中国:https://my.oschina.net/zbj161...
- 泡在网上的日子:http://www.jcodecraeer.com/me...
- 邮箱:yangchong211@163.com
- 阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV
- segmentfault头条:https://segmentfault.com/u/xi...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。