Java加密的常用的加密算法類型有三種
1單向加密:也就是不可逆的加密,例如MD5,SHA,HMAC
2對稱加密:也就是加密方和解密方利用同一個祕鑰對數據進行加密和解密,例如DES,PBE等等
3非對稱加密:非對稱加密分爲公鑰和祕鑰,二者是非對稱的,例如用私鑰加密的內容需要使用公鑰來解密,使用公鑰加密的內容需要用私鑰來解密,DSA,RSA…
關於keyGenerator,KeyPairGenerator,SecretKeyFactory的解析
keyGenerator:祕鑰生成器,也就是更具算法類型隨機生成一個祕鑰,例如HMAC,所以這個大部分用在非可逆的算法中
SecretKeyFactory:祕密祕鑰工廠,言外之意就是需要根據一個祕密(password)去生成一個祕鑰,例如DES,PBE,所以大部分使用在對稱加密中
KeyPairGenerator:祕鑰對生成器,也就是可以生成一對祕鑰,也就是公鑰和私鑰,所以大部分使用在非對稱加密中
代碼實現
祕鑰生成方式
祕鑰生成的時候只要SecureRandom種子不變,祕鑰不變;
如果需要每次生成不同的祕鑰,就可以使用系統自帶的種子;
/*
* @Description:生成祕鑰
* @Author:
* @Date:2019/8/8 15:27
*/
public class KeyGen {
/*****************************************************KeyGenerator生成祕鑰*****************************************************************/
public static SecretKey keyGenerator(String password) throws Exception{
SecureRandom random =new SecureRandom(password.getBytes());
//返回生成指定算法的祕密密鑰的 KeyGenerator 對象
KeyGenerator kg = KeyGenerator.getInstance("DES");
//初始化此密鑰生成器,使其具有確定的密鑰大小
kg.init(random);
//生成一個密鑰
SecretKey secretKey = kg.generateKey();
return secretKey;
}
/*********************************************************SecretKeyFactory生成祕鑰**********************************************************************************/
public static SecretKey secretKeyFactory(String password) throws Exception{
//實例化DES密鑰規則
DESKeySpec dks = new DESKeySpec(password.getBytes());
//實例化密鑰工廠
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
//生成密鑰
SecretKey secretKey = skf.generateSecret(dks);
return secretKey;
}
/**********************************************************KeyPairGenerator生成公鑰私鑰***********************************************************************************************************/
public static Map<String, byte[]> keyPairGeneratorByte(String password) throws IOException, NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
SecureRandom secureRandom = new SecureRandom(password.getBytes());
keyPairGenerator.initialize(1024, secureRandom);
KeyPair keyPair = keyPairGenerator.genKeyPair();
byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
Map<String, byte[]> map = new HashMap<String, byte[]>();
map.put("pub", publicKeyBytes);
map.put("pri", privateKeyBytes);
return map;
}
public static Map<String, Object> keyPairGenerator(String password) throws IOException, NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
SecureRandom secureRandom = new SecureRandom(password.getBytes());
keyPairGenerator.initialize(1024, secureRandom);
KeyPair keyPair = keyPairGenerator.genKeyPair();
byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
Map<String,Object> map = new HashMap<String, Object>();
map.put("pub", keyPair.getPublic());
map.put("pri", keyPair.getPrivate());
return map;
}
/*
* @Description:獲取公鑰
* @Param:[publicKey]
* @Date:2019/7/25 10:00
*/
public static PublicKey getPublicKey(byte[] publicKey) throws Exception {
X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
/*
* @Description:獲取私鑰
* @Param:[privateKey]
* @Date:2019/7/25 10:01
*/
public static PrivateKey getPrivateKey(byte[] privateKey) throws Exception {
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privateKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
}
1、單向加密
/*
* @Description:單向加密
* @Author:
* @Date:2019/8/8 9:16
*/
public class DxjmUtils {
/*
* @Description:md5生成數據長度爲16Byte,Sha生成20Byte,固定長度
* @Author:
* @Date:2019/8/8 9:58
*/
public static byte[] cactHash(byte[] bytes) {
byte[] _bytes = null;
try {
//可以選擇MD5加密或SHA加密
MessageDigest md = MessageDigest.getInstance("SHA1");
//數據加密 下面兩行代碼相當用於md.digest(bytes)
md.update(bytes);
_bytes = md.digest();
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
return _bytes;
}
public static void main(String[] arg) throws Base64DecodingException {
String str="測試";
byte[] jmstr=cactHash(str.getBytes());
byte[] jmstr1=cactHash(str.getBytes());
System.out.println(Base64.encode(jmstr));
System.out.println(Base64.encode(jmstr1));
}
}
2、對稱加密
/*
* @Description:對稱加密
* @Author:
* @Date:2019/8/8 10:03
*/
public class DcjmUtils {
/*
* @Description:加密
* @Author:
* @Date:2019/8/8 15:36
*/
public static byte[] encrypt(byte[] data, Key key) throws Exception{
//實例化
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
//使用密鑰初始化,設置爲加密模式
cipher.init(Cipher.ENCRYPT_MODE, key);
//執行操作
return cipher.doFinal(data);
}
/*
* @Description:解密
* @Author:
* @Date:2019/8/8 15:38
*/
public static byte[] decrypt(byte[] data,Key key) throws Exception{
//實例化
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
//使用密鑰初始化,設置爲解密模式
cipher.init(Cipher.DECRYPT_MODE, key);
//執行操作
return cipher.doFinal(data);
}
public static void main(String[] arg) throws Exception {
String str="測試";
//密碼不能小於8位否則報錯 throw new InvalidKeyException("Wrong key size");
SecretKey key= KeyGen.secretKeyFactory("abcdefgiabcdefgi");
byte[] enStr=encrypt(str.getBytes(),key);
byte[] deStr=decrypt(enStr,key);
System.out.println(Base64.encode(key.getEncoded()));
System.out.println(Base64.encode(enStr));
System.out.println(new String(deStr));
}
}
3、非對稱加密
/*
* @Description:非對稱加密
* @Author:
* @Date:2019/8/8 16:25
*/
public class FdcjmUtils {
/*
* @Description:非對稱公鑰加密
* @Author:
* @Date:2019/8/8 16:26
*/
public static byte[] encryptByPublicKey(byte[] data, PublicKey publicKey)
throws Exception {
// 對數據加密
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/*
* @Description:非對稱私鑰解密
* @Author:
* @Date:2019/8/8 16:29
*/
public static byte[] decrypt(byte data[], PrivateKey privateKey) throws Exception{
// 對數據解密
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
public static void main(String[] arg) throws Exception {
Map<String, byte[]> map= KeyGen.keyPairGeneratorByte("abcdefg");
//不使用隨機數加密,解密
String str="測試";
byte[] enStr= encryptByPublicKey(str.getBytes(),KeyGen.getPublicKey(map.get("pub")));
byte[] deStr= decrypt(enStr,KeyGen.getPrivateKey(map.get("pri")));
System.out.println(Base64.encode(enStr));
System.out.println(new String(deStr));
}
}