Android-RSA 分段加密解密
Android-Openssl創(chuàng)建RSA公鑰和私鑰
Android-AES加解密
Android-DH 秘鑰交換
1. AES(Advanced Encryption Standard) 介紹
AES 是比利時密碼學(xué)家Joan Daemen和Vincent Rijmen所設(shè)計的一種加密算法,又稱為 Rijndael 加密法垦写。由美國國家標(biāo)準(zhǔn)與技術(shù)研究院(NIST)經(jīng)過許多算法的篩選吕世,高級加密標(biāo)準(zhǔn)(Advanced Encryption Standard)在2001年11月26日發(fā)布于FIPS PUB 197,并在2002年5月26日成為有效的標(biāo)準(zhǔn)梯投,在全世界被廣泛使用命辖。
AES 是一種對稱加密算法,即使用秘鑰加密數(shù)據(jù)以后分蓖,要使用相同的秘鑰才能解密尔艇。AES 加密方式比 DES 加密更安全,但是速度比不上 DES么鹤,但在不同運行環(huán)境下能保持良好的性能终娃。
AES 共有 5 種加密模式:
- ECB(Electronic Code Book) 電子密碼本模式
- CBC(Cipher Block Chaining) 加密塊鏈模式
- CFB(Cipher FeedBack Mode) 加密反饋模式
- OFB(Output FeedBack) 輸出反饋模式
- CTR(Counter) 計數(shù)器模式(不常見)
其中 ECB、CBC蒸甜、CTR 為塊加密模式棠耕,CFB余佛、OFB 為流加密模式。
AES 五種加密模式: https://www.cnblogs.com/starwolf/p/3365834.html
2. AES 加解密
import android.util.Log;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* AES 對稱加密算法窍荧,加解密工具類
*/
public class AESEncrypt {
private static final String TAG = AESEncrypt.class.getSimpleName() + " --> ";
/**
* 加密算法
*/
private static final String KEY_ALGORITHM = "AES";
/**
* AES 的 密鑰長度辉巡,32 字節(jié),范圍:16 - 32 字節(jié)
*/
public static final int SECRET_KEY_LENGTH = 32;
/**
* 字符編碼
*/
private static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8;
/**
* 秘鑰長度不足 16 個字節(jié)時蕊退,默認(rèn)填充位數(shù)
*/
private static final String DEFAULT_VALUE = "0";
/**
* 加解密算法/工作模式/填充方式
*/
private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
/**
* AES 加密
*
* @param data 待加密內(nèi)容
* @param secretKey 加密密碼郊楣,長度:16 或 32 個字符
* @return 返回Base64轉(zhuǎn)碼后的加密數(shù)據(jù)
*/
public static String encrypt(String data, String secretKey) {
try {
//創(chuàng)建密碼器
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
//初始化為加密密碼器
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(secretKey));
byte[] encryptByte = cipher.doFinal(data.getBytes(CHARSET_UTF8));
// 將加密以后的數(shù)據(jù)進(jìn)行 Base64 編碼
return base64Encode(encryptByte);
} catch (Exception e) {
handleException(e);
}
return null;
}
/**
* AES 解密
*
* @param base64Data 加密的密文 Base64 字符串
* @param secretKey 解密的密鑰,長度:16 或 32 個字符
*/
public static String decrypt(String base64Data, String secretKey) {
try {
byte[] data = base64Decode(base64Data);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
//設(shè)置為解密模式
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(secretKey));
//執(zhí)行解密操作
byte[] result = cipher.doFinal(data);
return new String(result, CHARSET_UTF8);
} catch (Exception e) {
handleException(e);
}
return null;
}
/**
* 使用密碼獲取 AES 秘鑰
*/
public static SecretKeySpec getSecretKey(String secretKey) {
secretKey = toMakeKey(secretKey, SECRET_KEY_LENGTH, DEFAULT_VALUE);
return new SecretKeySpec(secretKey.getBytes(CHARSET_UTF8), KEY_ALGORITHM);
}
/**
* 如果 AES 的密鑰小于 {@code length} 的長度瓤荔,就對秘鑰進(jìn)行補位净蚤,保證秘鑰安全。
*
* @param secretKey 密鑰 key
* @param length 密鑰應(yīng)有的長度
* @param text 默認(rèn)補的文本
* @return 密鑰
*/
private static String toMakeKey(String secretKey, int length, String text) {
// 獲取密鑰長度
int strLen = secretKey.length();
// 判斷長度是否小于應(yīng)有的長度
if (strLen < length) {
// 補全位數(shù)
StringBuilder builder = new StringBuilder();
// 將key添加至builder中
builder.append(secretKey);
// 遍歷添加默認(rèn)文本
for (int i = 0; i < length - strLen; i++) {
builder.append(text);
}
// 賦值
secretKey = builder.toString();
}
return secretKey;
}
/**
* 將 Base64 字符串 解碼成 字節(jié)數(shù)組
*/
public static byte[] base64Decode(String data) {
return Base64.decode(data, Base64.NO_WRAP);
}
/**
* 將 字節(jié)數(shù)組 轉(zhuǎn)換成 Base64 編碼
*/
public static String base64Encode(byte[] data) {
return Base64.encodeToString(data, Base64.NO_WRAP);
}
/**
* 處理異常
*/
private static void handleException(Exception e) {
e.printStackTrace();
Log.e(TAG, TAG + e);
}
}
3. AES 加解密文件
/**
* 對文件進(jìn)行AES加密
*
* @param sourceFile 待加密文件
* @param dir 加密后的文件存儲路徑
* @param toFileName 加密后的文件名稱
* @param secretKey 密鑰
* @return 加密后的文件
*/
public static File encryptFile(File sourceFile, String dir, String toFileName, String secretKey) {
try {
// 創(chuàng)建加密后的文件
File encryptFile = new File(dir, toFileName);
// 根據(jù)文件創(chuàng)建輸出流
FileOutputStream outputStream = new FileOutputStream(encryptFile);
// 初始化 Cipher
Cipher cipher = initFileAESCipher(secretKey, Cipher.ENCRYPT_MODE);
// 以加密流寫入文件
CipherInputStream cipherInputStream = new CipherInputStream(
new FileInputStream(sourceFile), cipher);
// 創(chuàng)建緩存字節(jié)數(shù)組
byte[] buffer = new byte[1024 * 2];
// 讀取
int len;
// 讀取加密并寫入文件
while ((len = cipherInputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
outputStream.flush();
}
// 關(guān)閉加密輸入流
cipherInputStream.close();
closeStream(outputStream);
return encryptFile;
} catch (Exception e) {
handleException(e);
}
return null;
}
/**
* AES解密文件
*
* @param sourceFile 源加密文件
* @param dir 解密后的文件存儲路徑
* @param toFileName 解密后的文件名稱
* @param secretKey 密鑰
*/
public static File decryptFile(File sourceFile, String dir, String toFileName, String secretKey) {
try {
// 創(chuàng)建解密文件
File decryptFile = new File(dir, toFileName);
// 初始化Cipher
Cipher cipher = initFileAESCipher(secretKey, Cipher.DECRYPT_MODE);
// 根據(jù)源文件創(chuàng)建輸入流
FileInputStream inputStream = new FileInputStream(sourceFile);
// 獲取解密輸出流
CipherOutputStream cipherOutputStream = new CipherOutputStream(
new FileOutputStream(decryptFile), cipher);
// 創(chuàng)建緩沖字節(jié)數(shù)組
byte[] buffer = new byte[1024 * 2];
int len;
// 讀取解密并寫入
while ((len = inputStream.read(buffer)) >= 0) {
cipherOutputStream.write(buffer, 0, len);
cipherOutputStream.flush();
}
// 關(guān)閉流
cipherOutputStream.close();
closeStream(inputStream);
return decryptFile;
} catch (IOException e) {
handleException(e);
}
return null;
}
/**
* 初始化 AES Cipher
*
* @param secretKey 密鑰
* @param cipherMode 加密模式
* @return 密鑰
*/
private static Cipher initFileAESCipher(String secretKey, int cipherMode) {
try {
// 創(chuàng)建密鑰規(guī)格
SecretKeySpec secretKeySpec = getSecretKey(secretKey);
// 獲取密鑰
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// 初始化
cipher.init(cipherMode, secretKeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
return cipher;
} catch (Exception e) {
handleException(e);
}
return null;
}
/**
* 關(guān)閉流
*
* @param closeable 實現(xiàn)Closeable接口
*/
private static void closeStream(Closeable closeable) {
try {
if (closeable != null) closeable.close();
} catch (Exception e) {
handleException(e);
}
}