小序
字符串,byte[],文件等對象的加密和解密,是開發當中必不可少的操作。這裏僅基於不同方式的加解密實現,爲方便使用固聚合爲一個工具類使用,且代碼實現與前輩們的實現並沒有什麼太大的差別。有需要的親可直接帶走,如若有不正確的地方還望指正。
總覽
function | impact |
---|---|
String md5(String string) | MD5 文本加密 |
String md5(String string, int times) | MD5 文本多次加密 |
String md5(String string, String slat) | MD5 文本鹽值加密 |
String md5(File file, int style) | MD5 文件 IO/NIO 類型加密 |
String base64EncodeStr(String string) | Base64 文本加密 |
String base64DecodedStr(String string) | Base64 文本解密 |
String base64EncodeFile(File file) | Base64 文件加密 |
File base64DecodedFile(String filePath, String code) | Base64 文件 code 編碼解密 |
String aes(String content, String password, int type) | AES 加密/解密 |
String des(String content, String password, int type) | DES 加密/解密 |
String sha(String string, String type) | SHA 加密 |
byte[] rsa(byte[] data, String string, int type) | RSA 加密/解密 |
Map<String, Object> getKeyPair() |
獲取密鑰(公鑰/私鑰) |
String getKey(Map<String, Object> keyMap, boolean isPublicKey) |
根據上方密鑰獲取公鑰/私鑰 |
String sign(byte[] data, String privateKey) |
根據上方私鑰獲取數字簽名 |
boolean verify(byte[] data, String publicKey, String sign) |
數字簽名校驗 |
代碼
import android.annotation.SuppressLint;
import android.text.TextUtils;
import android.util.Base64;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
/**
* 加解密工具
*/
public class EncryptUtil {
private EncryptUtil() {
throw new UnsupportedOperationException("cannot be instantiated");
}
/**
* 二進位組轉十六進制字符串
*
* @param buf 二進位組
* @return 十六進制字符串
*/
private static String parseByte2HexStr(byte buf[]) {
StringBuilder sb = new StringBuilder();
for (byte b : buf) {
String hex = Integer.toHexString(b & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**
* 十六進制字符串轉二進位組
*
* @param hexStr 十六進制字符串
* @return 二進位組
*/
private static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1) return null;
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
/**
* MD5加密
*
* @param string 加密字符串
* @param slat 加密鹽值key
* @return 加密結果字符串
*/
public static String md5(String string, String slat) {
if (TextUtils.isEmpty(string)) return "";
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] bytes = md5.digest((string + slat).getBytes());
String result = "";
for (byte b : bytes) {
String temp = Integer.toHexString(b & 0xff);
if (temp.length() == 1) {
temp = "0" + temp;
}
result += temp;
}
return result;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* MD5加密
*
* @param string 加密字符串
* @return 加密結果字符串
* @see #md5(String, String)
*/
public static String md5(String string) {
return TextUtils.isEmpty(string) ? "" : md5(string, "");
}
/**
* MD5的IO文件加密類型
*/
public static final int MD5_TYPE_IO = 0;
/**
* MD5的NIO文件加密類型
*/
public static final int MD5_TYPE_NIO = 1;
/**
* MD5加密
*
* @param file 加密文件
* @param style 加密文件類型:{@link #MD5_TYPE_NIO} ,{@link #MD5_TYPE_IO}
* @return 加密結果字符串
*/
public static String md5(File file, int style) {
if (file == null || !file.isFile() || !file.exists()) return "";
FileInputStream in = null;
String result = "";
byte buffer[] = new byte[8192];
int len;
try {
in = new FileInputStream(file);
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] bytes = md5.digest();
if (style == MD5_TYPE_IO) {
while ((len = in.read(buffer)) != -1) {
md5.update(buffer, 0, len);
}
} else {
MappedByteBuffer byteBuffer = in.getChannel().map(
FileChannel.MapMode.READ_ONLY, 0, file.length());
md5.update(byteBuffer);
}
for (byte b : bytes) {
String temp = Integer.toHexString(b & 0xff);
if (temp.length() == 1) {
temp = "0" + temp;
}
result += temp;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
/**
* MD5加密
*
* @param string 加密字符串
* @param times 重複加密次數
* @return 加密結果字符串
*/
public static String md5(String string, int times) {
if (TextUtils.isEmpty(string)) return "";
String md5 = md5(string);
for (int i = 0; i < times; i++) md5 = md5(md5);
return md5;
}
/**
* Base64加密
*
* @param string 加密字符串
* @return 加密結果字符串
*/
public static String base64EncodeStr(String string) {
if (TextUtils.isEmpty(string)) return "";
return Base64.encodeToString(string.getBytes(), Base64.DEFAULT);
}
/**
* Base64解密
*
* @param string 解密字符串
* @return 解密結果字符串
*/
public static String base64DecodedStr(String string) {
if (TextUtils.isEmpty(string)) return "";
return new String(Base64.decode(string, Base64.DEFAULT));
}
/**
* Base64加密
*
* @param file 加密文件
* @return 加密結果字符串
*/
public static String base64EncodeFile(File file) {
if (null == file) return "";
try {
FileInputStream inputFile = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
inputFile.read(buffer);
inputFile.close();
return Base64.encodeToString(buffer, Base64.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
/**
* Base64解密
*
* @param filePath 解密文件路徑
* @param code 解密文件編碼
* @return 解密結果文件
*/
public static File base64DecodedFile(String filePath, String code) {
if (TextUtils.isEmpty(filePath) || TextUtils.isEmpty(code)) {
return null;
}
File desFile = new File(filePath);
try {
byte[] decodeBytes = Base64.decode(code.getBytes(), Base64.DEFAULT);
FileOutputStream fos = new FileOutputStream(desFile);
fos.write(decodeBytes);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
return desFile;
}
/**
* Aes加密/解密
*
* @param content 字符串
* @param password 密鑰
* @param type 加密:{@link Cipher#ENCRYPT_MODE},解密:{@link Cipher#DECRYPT_MODE}
* @return 加密/解密結果字符串
*/
public static String aes(String content, String password, int type) {
try {
KeyGenerator generator = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");
secureRandom.setSeed(password.getBytes());
generator.init(128, secureRandom);
SecretKey secretKey = generator.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
@SuppressLint("GetInstance") Cipher cipher = Cipher.getInstance("AES");
cipher.init(type, key);
if (type == Cipher.ENCRYPT_MODE) {
byte[] byteContent = content.getBytes("utf-8");
return parseByte2HexStr(cipher.doFinal(byteContent));
} else {
byte[] byteContent = parseHexStr2Byte(content);
return new String(cipher.doFinal(byteContent));
}
} catch (NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException |
UnsupportedEncodingException | InvalidKeyException | NoSuchPaddingException |
NoSuchProviderException e) {
e.printStackTrace();
}
return null;
}
/**
* Des加密/解密
*
* @param content 字符串內容
* @param password 密鑰
* @param type 加密:{@link Cipher#ENCRYPT_MODE},解密:{@link Cipher#DECRYPT_MODE}
* @return 加密/解密結果
*/
public static String des(String content, String password, int type) {
try {
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(password.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
@SuppressLint("GetInstance") Cipher cipher = Cipher.getInstance("DES");
cipher.init(type, keyFactory.generateSecret(desKey), random);
if (type == Cipher.ENCRYPT_MODE) {
byte[] byteContent = content.getBytes("utf-8");
return parseByte2HexStr(cipher.doFinal(byteContent));
} else {
byte[] byteContent = parseHexStr2Byte(content);
return new String(cipher.doFinal(byteContent));
}
} catch (NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException |
UnsupportedEncodingException | InvalidKeyException | NoSuchPaddingException |
InvalidKeySpecException e) {
e.printStackTrace();
}
return null;
}
/**
* Sha加密類型
*/
public final static String SHA224 = "sha-224";
/**
* Sha加密類型
*/
public final static String SHA256 = "sha-256";
/**
* Sha加密類型
*/
public final static String SHA384 = "sha-384";
/**
* Sha加密類型
*/
public final static String SHA512 = "sha-512";
/**
* Sha加密
*
* @param string 加密字符串
* @param type 加密類型 :{@link #SHA224},{@link #SHA256},{@link #SHA384},{@link #SHA512}
* @return SHA加密結果字符串
*/
public static String sha(String string, String type) {
if (TextUtils.isEmpty(string)) return "";
if (TextUtils.isEmpty(type)) type = SHA256;
try {
MessageDigest md5 = MessageDigest.getInstance(type);
byte[] bytes = md5.digest((string).getBytes());
String result = "";
for (byte b : bytes) {
String temp = Integer.toHexString(b & 0xff);
if (temp.length() == 1) {
temp = "0" + temp;
}
result += temp;
}
return result;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* 隨機獲取密鑰(公鑰和私鑰), 客戶端公鑰加密,服務器私鑰解密
*
* @return 結果密鑰對
* @throws Exception
*/
public static Map<String, Object> getKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", "BC");
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<>(2);
keyMap.put("RSAPublicKey", publicKey);
keyMap.put("RSAPrivateKey", privateKey);
return keyMap;
}
/**
* 獲取公鑰/私鑰
*
* @param keyMap 密鑰對
* @param isPublicKey true:獲取公鑰,false:獲取私鑰
* @return 獲取密鑰字符串
*/
public static String getKey(Map<String, Object> keyMap, boolean isPublicKey) {
Key key = (Key) keyMap.get(isPublicKey ? "RSAPublicKey" : "RSAPrivateKey");
return new String(Base64.encode(key.getEncoded(), Base64.DEFAULT));
}
/**
* 獲取數字簽名
*
* @param data 二進制位
* @param privateKey 私鑰(BASE64編碼)
* @return 數字簽名結果字符串
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64.decode(privateKey.getBytes(), Base64.DEFAULT);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(privateK);
signature.update(data);
return new String(Base64.encode(signature.sign(), Base64.DEFAULT));
}
/**
* 數字簽名校驗
*
* @param data 二進位組
* @param publicKey 公鑰(BASE64編碼)
* @param sign 數字簽名字符串
* @return true:校驗成功,false:校驗失敗
* @throws Exception
*/
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
byte[] keyBytes = Base64.decode(publicKey.getBytes(), Base64.DEFAULT);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance("MD5withRSA");
signature.initVerify(publicK);
signature.update(data);
return signature.verify(Base64.decode(sign.getBytes(), Base64.DEFAULT));
}
/**
* Rsa公鑰加密類型
*/
public static final int RSA_PUBLIC_ENCRYPT = 0;
/**
* Rsa公鑰解密類型
*/
public static final int RSA_PUBLIC_DECRYPT = 1;
/**
* Rsa私鑰加密類型
*/
public static final int RSA_PRIVATE_ENCRYPT = 2;
/**
* Rsa私鑰解密類型
*/
public static final int RSA_PRIVATE_DECRYPT = 3;
/**
* Rsa加密/解密(一般情況下,公鑰加密私鑰解密)
*
* @param data 源數據
* @param string 密鑰(BASE64編碼)
* @param type 操作類型:{@link #RSA_PUBLIC_ENCRYPT},{@link #RSA_PUBLIC_DECRYPT},{@link #RSA_PRIVATE_ENCRYPT},{@link #RSA_PRIVATE_DECRYPT}
* @return 加密/解密結果字符串
* @throws Exception
*/
public static byte[] rsa(byte[] data, String string, int type) throws Exception {
byte[] keyBytes = Base64.decode(string, Base64.DEFAULT);
Key key;
KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PUBLIC_DECRYPT) {
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
key = keyFactory.generatePublic(x509KeySpec);
} else {
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
key = keyFactory.generatePrivate(pkcs8KeySpec);
}
// 對數據加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 對數據分段加密
if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PRIVATE_ENCRYPT) {
cipher.init(Cipher.ENCRYPT_MODE, key);
while (inputLen - offSet > 0) {
cache = cipher.doFinal(data, offSet, inputLen - offSet > 117 ? 117 : inputLen - offSet);
out.write(cache, 0, cache.length);
i++;
offSet = i * 117;
}
} else {
cipher.init(Cipher.DECRYPT_MODE, key);
while (inputLen - offSet > 0) {
if (inputLen - offSet > 128) {
cache = cipher.doFinal(data, offSet, 128);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * 128;
}
}
byte[] result = out.toByteArray();
out.close();
return result;
}
}
實現
md5
// 字符串加密
String str = "123456";
System.out.println("一次加密:" + Encryption.md5(str));
System.out.println("二次加密:" + Encryption.md5(str, 2));
System.out.println("鹽值加密:" + Encryption.md5(str, "78"));
System.out: 一次加密:e10adc3949ba59abbe56e057f20f883e
System.out: 二次加密:c56d0e9a7ccec67b4ea131655038d604
System.out: 鹽值加密:25d55ad283aa400af464c76d713c07ad
// 文件加密
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
System.out.println("IO文件加密:" + EncryptUtil.md5(getBitmap2File(bmp), EncryptUtil.MD5_TYPE_IO));
System.out.println("NIO文件加密:" + EncryptUtil.md5(getBitmap2File(bmp), EncryptUtil.MD5_TYPE_NIO));
I/System.out: IO文件加密:d41d8cd98f00b204e9800998ecf8427e
I/System.out: NIO文件加密:d41d8cd98f00b204e9800998ecf8427e
Base64
// 字符串加解密
String baseStr = EncryptUtil.base64EncodeStr("123456");
System.out.println("base64字符串加密:" + baseStr);
System.out.println("base64字符串解密:" + EncryptUtil.base64DecodedStr(baseStr));
I/System.out: base64字符串加密:MTIzNDU2
I/System.out: base64字符串解密:123456
// 文件加解密
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
String baseFile = EncryptUtil.base64EncodeFile(getBitmap2File(bmp));
System.out.println("base64文件加密:" + baseFile);
System.out.println("base64文件解密:" + EncryptUtil.base64DecodedFile("/mnt/sdcard/01.jpg", baseFile));
I/System.out: base64文件加密:
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB…I/System.out: base64文件解密:/mnt/sdcard/01.jpg
AES
// 對象加解密
String key = "1234567890123456";
String aesStr = EncryptUtil.aes("gzejia", key, Cipher.ENCRYPT_MODE);
System.out.println("aes對象加密: " + aesStr);
System.out.println("aes對象解密: " + EncryptUtil.aes(aesStr, key, Cipher.DECRYPT_MODE));
I/System.out: aes對象加密: 7E8886393DD34B24CC51B1A9D030DB5A
I/System.out: aes對象解密: gzejia
javax.crypto.BadPaddingException: pad block corrupted,出現該異常的主導原因可能如下:
- 密鑰key長度不足16位
- 缺少 SecureRandom secureRandom = SecureRandom.getInstance(“SHA1PRNG”, “Crypto”);
DES
String key = "1234567890123456";
String desStr = EncryptUtil.des("gzejia", key, Cipher.ENCRYPT_MODE);
System.out.println("des對象加密: " + desStr);
System.out.println("des對象解密: " + EncryptUtil.des(desStr, key, Cipher.DECRYPT_MODE));
I/System.out: des對象加密: 552E6962E5187580
I/System.out: des對象解密: gzejia
SHA
String shaStr = "gzejia";
System.out.println("sha_SHA224對象加密: " + EncryptUtil.sha(shaStr, EncryptUtil.SHA224));
System.out.println("sha_SHA256對象加密: " + EncryptUtil.sha(shaStr, EncryptUtil.SHA256));
System.out.println("sha_SHA384對象加密: " + EncryptUtil.sha(shaStr, EncryptUtil.SHA384));
System.out.println("sha_SHA512對象加密: " + EncryptUtil.sha(shaStr, EncryptUtil.SHA512));
I/System.out: sha_SHA224對象加密:
36e2a37256a87dda91e8dacf9662c49461ecfc68d65488857c146e59I/System.out: sha_SHA256對象加密:
94a9222df72d5927d1996203b0b186ab857d9055db54b48277bf943272b19fc1I/System.out: sha_SHA384對象加密:
ea8e751bdfccb96715a37153a831fc935e2986743de72b32941043c1960f2e2ab7d71b965dda42cd128a837191e4667aI/System.out: sha_SHA512對象加密:
a5e7bea71af1fccdc1f3d353df08013e2bebe8e0a49b435512bdc855f36589cffbf1ac1825e2357a4a4f8b5295173928f76a806ba0c77c2a7ba3ef068cdf3ced
RSA
try {
byte[] data = "gzejia有中文".getBytes();
// 密鑰與數字簽名獲取
Map<String, Object> keyMap = EncryptUtil.getKeyPair();
String publicKey = EncryptUtil.getKey(keyMap, true);
System.out.println("rsa獲取公鑰: " + publicKey);
String privateKey = EncryptUtil.getKey(keyMap, false);
System.out.println("rsa獲取私鑰: " + privateKey);
// 公鑰加密私鑰解密
byte[] rsaPublic =
EncryptUtil.rsa(data, publicKey, EncryptUtil.RSA_PUBLIC_ENCRYPT);
System.out.println("rsa公鑰加密: " + new String(rsaPublic));
System.out.println("rsa私鑰解密: " + new String(
EncryptUtil.rsa(rsaPublic, privateKey, EncryptUtil.RSA_PRIVATE_DECRYPT)));
// 私鑰加密公鑰解密
byte[] rsaPrivate =
EncryptUtil.rsa(data, privateKey, EncryptUtil.RSA_PRIVATE_ENCRYPT);
System.out.println("rsa私鑰加密: " + new String(rsaPrivate));
System.out.println("rsa公鑰解密: " + new String(
EncryptUtil.rsa(rsaPrivate, publicKey, EncryptUtil.RSA_PUBLIC_DECRYPT)));
// 私鑰簽名及公鑰簽名校驗
String signStr = EncryptUtil.sign(rsaPrivate, privateKey);
System.out.println("rsa數字簽名生成: " + signStr);
System.out.println("rsa數字簽名校驗: " +
EncryptUtil.verify(rsaPrivate, publicKey, signStr));
} catch (Exception e) {
e.printStackTrace();
}
I/System.out: rsa獲取公鑰:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3W84EWgATxN4OfjXUResyzy+lf/8TDDmHtRkh…I/System.out: rsa獲取私鑰:
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALdbzgRaABPE3g5+NdRF6zLPL6V/…I/System.out: rsa公鑰加密:o�ZW�Ay����&�d��qa�h�]�ɟ�Ӵ�Rg1�0#…
I/System.out: rsa私鑰解密: gzejia有中文
I/System.out: rsa私鑰加密: � ��IA�{�R�+�y�_����%�=��…
I/System.out: rsa公鑰解密: gzejia有中文
I/System.out: rsa數字簽名生成:
XYHhwM2d+qUOWfTvi4l0Xh0JHlgf4zOBz81wahV90dxHhoqbi/HG6PlmkPnFnnZAkB5X8VMRKumK…I/System.out: rsa數字簽名校驗: true
java.security.spec.InvalidKeySpecException:
java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag,解決途徑:
原語句: KeyFactory keyf = KeyFactory.getInstance(“RSA”);
更改爲:KeyFactory keyFactory = KeyFactory.getInstance(“RSA”, “BC”);
場景普及
對稱加密
加密和解密用的是同一個密鑰
非對稱加密
密鑰對(即公鑰與私鑰),分別負責加密或解密的任務
非對稱加密+對稱加密
主對稱加密,以非對稱加密方式傳輸對稱加密密鑰