目錄介紹
- 1.加密和解密
- 1.1 問答環(huán)節(jié)
- 1.2 加解密概況
- 2.對稱加密和非對稱加密
- 2.1 什么是對稱加密
- 2.2 什么是非對稱加密
- 2.3 常見對稱加密有什么
- 2.4 常見非對稱加密有什么
- 2.5 非對稱加密用途
- 3.關(guān)于單向加密
- 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加密內(nèi)容長度限制問題
- 5.6 加解密效率測試
- 5.7 分段加密解密工具類代碼
好消息
- 博客筆記大匯總【16年3月到至今】,包括Java基礎(chǔ)及深入知識(shí)點(diǎn),Android技術(shù)博客,Python學(xué)習(xí)筆記等等,還包括平時(shí)開發(fā)中遇到的bug匯總,長期更新維護(hù)并且修正,持續(xù)完善……開源的文件是markdown格式的!轉(zhuǎn)載請注明出處,謝謝!
- https://github.com/yangchong211/YCBlogs
1.加密和解密
1.1 問答環(huán)節(jié)
- 1.1.1 常見的加密和解密有哪些?
- 1.1.2 MD5加密是屬于什么類型?是否可逆,以及有哪些應(yīng)用場景?
- 1.1.3 實(shí)際開發(fā)中有哪些加解密的應(yīng)用場景?
1.2 加解密概況
- 1)在對稱加密算法中,雙方使用的密鑰相同,要求解密方事先必須知道加密密鑰。這類加密算法技術(shù)較為成熟,加密效率高。
- 2)在非對稱加密算法中,收發(fā)雙方使用不同的密鑰,發(fā)方使用公開密鑰對消息進(jìn)行加密,收發(fā)使用私有密鑰機(jī)型解密,保密性更高,但效率更低。
- 3)單向加密算法在加密過程中不需要使用密鑰,輸入明文后由算法直接加密成密文,密文無法解密,只有重新輸入密文,并經(jīng)過同樣的加密算法處理,得到形同的密文并被系統(tǒng)重新識(shí)別后,才能真正的解密,這種算法非常復(fù)雜,通常只在數(shù)據(jù)量有限的情形下使用,如廣泛應(yīng)用在計(jì)算機(jī)系統(tǒng)中的口令加密等。
2.對稱加密和非對稱加密
2.1 什么是對稱加密
- 密鑰可以自己指定,只有一把密鑰,如果密鑰暴露,文件就會(huì)被暴露
- 特點(diǎn)是加密速度很快,但是缺點(diǎn)是安全性較低,因?yàn)橹灰荑€暴漏,數(shù)據(jù)就可以被解密了。
- 一句話概括:加密和解密都是用相同密鑰
2.2 什么是非對稱加密
- 有兩把鑰匙(密鑰對),公鑰和私鑰,公鑰的話給別人,私鑰自己保存
- 把密鑰通常是通過程序生成,不能自己指定
- 特點(diǎn)是加密速度慢些,但是安全系數(shù)很高
- 加密和解密的規(guī)則是:公鑰加密只能私鑰解密,私鑰加密只能公鑰解密
- 應(yīng)用場景舉例:在集成支付寶支付sdk時(shí),需要生成私鑰和公鑰,公鑰需要設(shè)置到支付寶網(wǎng)站的管理后臺(tái),在程序中調(diào)用支付接口的時(shí)候,使用我們自己的私鑰進(jìn)行加密,這樣支付寶由于有公鑰可以解密,其他人即時(shí)劫持了數(shù)據(jù),但是沒有公鑰,也無法解密。
- image
2.3 常見對稱加密有什么
- DES算法(Data Encryption Standard)
- AES算法(Advanced Encryption Standard)
2.4 常見非對稱加密有什么
- RSA
2.5 非對稱加密用途
- 身份認(rèn)證
- 一條加密信息若能用A 的公鑰能解開,則該信息一定是用A 的私鑰加密的,該能確定該用戶是A。
- image
- 陌生人通信
- A 和B 兩個(gè)人互不認(rèn)識(shí),A把自己的公鑰發(fā)給B,B也把自己的公鑰發(fā)給A,則雙方可以通過對方的公鑰加密信息通信。C 雖然也能得到A、B 的公鑰,但是他解不開密文。
- image
- 支付寶支付加密
- 具體可以參考支付寶sdk的官方demo
3.關(guān)于單向加密
- MD5
- 關(guān)于MD5加密的工具類代碼如下所示
4.加密和解密代碼展示
4.1 DES加密和解密【對稱加密】
-
加密過程
- 需要加密的內(nèi)容,也就是明文;然后需要密鑰。最后通過工具類加密得到加密后的密文
private final String desEncryptString = "yangchong"; private final String desEncryptKey = "19930311"; s1 = DES.encryptDES(desEncryptString, desEncryptKey); Log.e("加密和解密", s1); 加密和解密: 84r1gS+D3Op8yrSnF5ZDrQ== //s1為加密后的密文 -
解密過程
- 利用加密后的密文,與設(shè)置的key,也就是密鑰,則可以解密得到加密的內(nèi)容
String s2 = DES.decryptDES(s1, desEncryptKey); Log.e("加密和解密", s2); //加密和解密: yangchong
- Android中實(shí)現(xiàn)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 {
//實(shí)例化IvParameterSpec對象,使用指定的初始化向量
IvParameterSpec zeroIv=new IvParameterSpec(iv);
//實(shí)例化SecretKeySpec,根據(jù)傳入的密鑰獲得字節(jié)數(shù)組來構(gòu)造SecretKeySpec
SecretKeySpec key =new SecretKeySpec(encryptKey.getBytes(),"DES");
//創(chuàng)建密碼器
Cipher cipher=Cipher.getInstance("DES/CBC/PKCS5Padding");
//用密鑰初始化Cipher對象
cipher.init(Cipher.ENCRYPT_MODE,key,zeroIv);
//執(zhí)行加密操作
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);
//實(shí)例化IvParameterSpec對象使用指定的初始化向量
IvParameterSpec zeroIv=new IvParameterSpec(iv);
//實(shí)例化SecretKeySpec,根據(jù)傳入的密鑰獲得字節(jié)數(shù)組來構(gòu)造SecretKeySpec,
SecretKeySpec key=new SecretKeySpec(decryptKey.getBytes(),"DES");
//創(chuàng)建密碼器
Cipher cipher=Cipher.getInstance("DES/CBC/PKCS5Padding");
//用密鑰初始化Cipher對象,上面是加密,這是解密模式
cipher.init(Cipher.DECRYPT_MODE,key,zeroIv);
//獲取解密后的數(shù)據(jù)
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";
//加密函數(shù),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);
}
//解密函數(shù)。key值必須和加密時(shí)的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 強(qiáng)隨機(jī)種子算法, 要區(qū)別Android 4.2.2以上版本的調(diào)用方法
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 公鑰加密,私鑰解密
-
第一步:獲取隨機(jī)的公鑰和私鑰
- 代碼如下所示:
//秘鑰默認(rèn)長度 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(); } -
第二步:公鑰加密
- 代碼如下所示:
//用公鑰對字符串進(jìn)行加密 try { bytes = RSA.encryptByPublicKey(DEFAULT_SPLIT, publicKey.getEncoded()); String s = new String(bytes); Log.e("加密和解密", s); } catch (Exception e) { e.printStackTrace(); } -
第三步:私鑰解密
//使用私鑰進(jìn)行解密 try { byte[] bytes = RSA.decryptByPrivateKey(this.bytes, privateKey.getEncoded()); String s = new String(bytes); Log.e("加密和解密", s); //解密后得到的數(shù)據(jù):yangchong } catch (Exception e) { e.printStackTrace(); }
5.2 私鑰加密,公鑰解密
-
第一步:獲取隨機(jī)的公鑰和私鑰
- 代碼如下所示:
//秘鑰默認(rèn)長度 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); //解密后得到的數(shù)據(jù):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";//加密填充方式 /** * 隨機(jī)生成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; } } /*-------------------------------------------------------------------------------------------------*/ /** * 用公鑰對字符串進(jìn)行加密 * @param data 原文 * @param publicKey 密鑰 * @return byte[] 解密數(shù)據(jù) */ 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); // 加密數(shù)據(jù) Cipher cp = Cipher.getInstance(ECB_PKCS1_PADDING); cp.init(Cipher.ENCRYPT_MODE, keyPublic); return cp.doFinal(data); } /** * 私鑰加密 * * @param data 待加密數(shù)據(jù) * @param privateKey 密鑰 * @return byte[] 解密數(shù)據(jù) */ 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); // 數(shù)據(jù)加密 Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING); cipher.init(Cipher.ENCRYPT_MODE, keyPrivate); return cipher.doFinal(data); } /** * 公鑰解密 * * @param data 待解密數(shù)據(jù) * @param publicKey 密鑰 * @return byte[] 解密數(shù)據(jù) */ 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); // 數(shù)據(jù)解密 Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING); cipher.init(Cipher.DECRYPT_MODE, keyPublic); return cipher.doFinal(data); } /** * 使用私鑰進(jìn)行解密 * @param encrypted 待解密數(shù)據(jù) * @param privateKey 密鑰 * @return byte[] 解密數(shù)據(jù) * @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); // 解密數(shù)據(jù) Cipher cp = Cipher.getInstance(ECB_PKCS1_PADDING); cp.init(Cipher.DECRYPT_MODE, keyPrivate); byte[] arr = cp.doFinal(encrypted); return arr; } }
5.4 注意RSA加密填充方式
- 之前以為上面操作就能實(shí)現(xiàn)rsa加解密,以為可以呢,但是遇到Android這邊加密過的數(shù)據(jù),服務(wù)器端死活解密不了,原來android系統(tǒng)的RSA實(shí)現(xiàn)是"RSA/None/NoPadding",而標(biāo)準(zhǔn)JDK實(shí)現(xiàn)是"RSA/None/PKCS1Padding",這造成了在android機(jī)上加密后無法在服務(wù)器上解密的原因,所以在實(shí)現(xiàn)的時(shí)候這個(gè)一定要注意這個(gè)問題。
5.5 RSA加密內(nèi)容長度限制問題
- RSA非對稱加密內(nèi)容長度有限制,1024位key的最多只能加密127位數(shù)據(jù),否則就會(huì)報(bào)錯(cuò)(javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes)
- RSA 算法規(guī)定:待加密的字節(jié)數(shù)不能超過密鑰的長度值除以 8 再減去 11(即:KeySize / 8 - 11),而加密后得到密文的字節(jié)數(shù),正好是密鑰的長度值除以 8(即:KeySize / 8)。
5.6 加解密效率測試
-
第一步:獲取隨機(jī)的公鑰和私鑰
- 代碼如下所示:
//秘鑰默認(rèn)長度 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(); } -
第二步:用公鑰對對象進(jìn)行加密
- 代碼如下所示:
//用公鑰對對象進(jìn)行加密 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","公鑰加密耗時(shí) cost time---->"+(end-start)); String encryStr = new String(encryptBytes); Log.e("YC","加密前數(shù)據(jù)長度 --1-->"+string.length()); Log.e("YC","加密后數(shù)據(jù)長度 --1-->"+encryStr.length()); -
第三步:使用私鑰進(jìn)行解密
//使用私鑰進(jìn)行解密 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","私鑰解密耗時(shí) cost time---->"+(end2-start2)); Log.e("YC","解密后數(shù)據(jù) --1-->"+decryStr); -
第四步:加密和解密效率比較
- 如下所示
- 加密后數(shù)據(jù)大小的變化:數(shù)據(jù)量差不多是加密前的1.6倍
- 經(jīng)過幾次測試可知,解密要比加密費(fèi)時(shí)間多,所以一般建議在服務(wù)端做解密的邏輯操作
- image
5.7 分段加密解密工具類代碼
- 代碼如下所示
//秘鑰默認(rèn)長度 private static final int DEFAULT_KEY_SIZE = 2048; // 當(dāng)前秘鑰支持加密的最大字節(jié)數(shù) private static final int DEFAULT_BUFFER_SIZE = (DEFAULT_KEY_SIZE / 8) - 11; // 當(dāng)要加密的內(nèi)容超過bufferSize,則采用partSplit進(jìn)行分塊加密 private static final byte[] DEFAULT_SPLIT = "#PART#".getBytes(); /** * 用公鑰對字符串進(jìn)行分段加密 * @param data 需要加密數(shù)據(jù) * @param publicKey 公鑰 * @return byte[] 加密數(shù)據(jù) * @throws Exception 異常 * https://github.com/yangchong211 */ 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; } /** * 用秘鑰對字符串進(jìn)行分段加密 * * @param data 要加密的原始數(shù)據(jù) * @param privateKey 秘鑰 * @return byte[] 加密數(shù)據(jù) * @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 待解密數(shù)據(jù) * @param publicKey 公鑰 * @return byte[] 解密數(shù)據(jù) * @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]) { // 這個(gè)是以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) { // 驗(yàn)證到split的最后一位,都沒有break,則表明已經(jīng)確認(rèn)是split段 isMatchSplit = true; } } } } else { // split只有一位,則已經(jīng)匹配了 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 待解密數(shù)據(jù) * @param privateKey 私鑰 * @return byte[] 解密數(shù)據(jù) * @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]) { // 這個(gè)是以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) { // 驗(yàn)證到split的最后一位,都沒有break,則表明已經(jīng)確認(rèn)是split段 isMatchSplit = true; } } } } else { // split只有一位,則已經(jīng)匹配了 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; }
關(guān)于其他內(nèi)容介紹
01.關(guān)于博客匯總鏈接
- 1.技術(shù)博客匯總
- 2.開源項(xiàng)目匯總
- 3.生活博客匯總
- 4.喜馬拉雅音頻匯總
- 5.其他匯總
02.關(guān)于我的博客
- 我的個(gè)人站點(diǎn):www.yczbj.org,www.ycbjie.cn
- github:https://github.com/yangchong211
- 知乎:https://www.zhihu.com/people/yang-chong-69-24/pins/posts
- 簡書:http://www.itdecent.cn/u/b7b2c6ed9284
- csdn:http://my.csdn.net/m0_37700275
- 喜馬拉雅聽書:http://www.ximalaya.com/zhubo/71989305/
- 開源中國:https://my.oschina.net/zbj1618/blog
- 泡在網(wǎng)上的日子:http://www.jcodecraeer.com/member/content_list.php?channelid=1
- 郵箱:yangchong211@163.com
- 阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100- 239.headeruserinfo.3.dT4bcV
- segmentfault頭條:https://segmentfault.com/u/xiangjianyu/articles



