目录
定义
原文通过加密秘钥生成密文,密文通过解密秘钥得到原文。
对于加密秘钥和解密秘钥是相同的算法,就叫对称加密算法。
常用对称加密算法
DES
Data Encryption Standard
初代对称加密算法
从98年开始不断被破解,到现在已经完全不具备安全性了。
现在基本没人用了,但很值得学习。
秘钥长度56位
3DES
由于DES算法长度不够,衍生出2重DES算法,3重DES算法,4重DES算法等。
用的最多的是3重DES算法。
3重DES,秘钥长度增加,迭代次数增加。
秘钥长度112或168,默认168。
AES
由于3DES效率有些低,所以又有了AES加密算法。
AES是目前使用最多的对称加密算法。而且至今未被破解。
常用于移动通信系统加密和一些基于SSH协议的软件(SSH Client、secureCRT)。
AES秘钥长度128或192或256,默认128。
额外注意,用JDK的实现中,使用256位秘钥需要获得无政府限制权限文件(美国政府的限制,所以一般场景不用)。
PEB
PBE(password based encryption),基于口令的加密算法。
PBE算法,其实是对之前的AES、DES的包装升级。
口令一般是用户自己创建管理的。为了防止暴力破解,要对口令进行加盐操作。
常用的PEB算法:
PBEWithMD5AndDES,秘钥长度56位
PBEWithMD5AndTripleDES,秘钥长度112、168位,默认168位
PBEWithSHA1AndDESede,秘钥长度112、168位,默认168位
PBEWithSHA1AndRC2_40,秘钥长度40~1024位(8的倍数),默认128位
常用对称加密算法的java实现
DES实现
import org.apache.commons.codec.binary.Hex;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/** * @Author: zhangshuai * @Date: 2020-04-22 22:38 * @Description: **/
public class DESTest {
public static void main(String[] args) throws Exception {
String name = "hello word";
String password = getPassword();
// String password = "1122334455667788";
System.out.println("秘钥:"+password);
byte[] encrypt = encrypt(name.getBytes(), password);
String encryptString = Hex.encodeHexString(encrypt);
System.out.println("秘钥加密后的密文:"+encryptString);
byte[] decodeHex = Hex.decodeHex(encryptString.toCharArray());
byte[] decrypt = decrypt(decodeHex, password);
System.out.println("秘钥解密后的明文:"+new String(decrypt));
}
/** * 获取随机秘钥 */
public static String getPassword() throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
keyGenerator.init(56);
SecretKey secretKey = keyGenerator.generateKey();
byte[] keyEncoded = secretKey.getEncoded();
return Hex.encodeHexString(keyEncoded);
}
/** * 加密 */
public static byte[] encrypt(byte[] datasource, String password) {
try{
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(password.getBytes());
//密匙工厂
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(desKey);
//Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("DES");
//用密匙初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
//现在,获取数据并加密
//正式执行加密操作
return cipher.doFinal(datasource);
}catch(Throwable e){
e.printStackTrace();
}
return null;
}
/** * 解密 */
public static byte[] decrypt(byte[] src, String password) throws Exception {
// DES算法要求有一个可信任的随机数源
SecureRandom random = new SecureRandom();
// 创建一个DESKeySpec对象
DESKeySpec desKey = new DESKeySpec(password.getBytes());
// 密匙工厂
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// 将DESKeySpec对象转换成SecretKey对象
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, securekey, random);
// 解密
return cipher.doFinal(src);
}
}
3DES实现
import org.apache.commons.codec.binary.Hex;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
public class Test3DES {
public static void main(String[] args) throws Exception {
String name = "hello word";
byte[] password = getPassword();
System.out.println("秘钥:" + Hex.encodeHexString(password));
byte[] encrypt = encrypt(name.getBytes(), password);
String encryptString = Hex.encodeHexString(encrypt);
System.out.println("秘钥加密后的密文:" + encryptString);
byte[] decodeHex = Hex.decodeHex(encryptString.toCharArray());
byte[] decrypt = decrypt(decodeHex, password);
System.out.println("秘钥解密后的明文:" + new String(decrypt));
}
/** * 获取随机秘钥 */
public static byte[] getPassword() throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
keyGenerator.init(168);
SecretKey secretKey = keyGenerator.generateKey();
byte[] keyEncoded = secretKey.getEncoded();
return keyEncoded;
}
/** * 秘钥转换为DESede专用密钥 */
private static Key getSecretKey(byte[] key) {
try {
DESedeKeySpec deSedeKeySpec = new DESedeKeySpec(key);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
Key secretKey = factory.generateSecret(deSedeKeySpec);
return secretKey;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/** * 加密 */
public static byte[] encrypt(byte[] datasource, byte[] password) {
try {
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
// 创建密码器
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));
// 初始化为加密模式的密码器
byte[] result = cipher.doFinal(datasource);// 加密
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/** * 解密 */
public static byte[] decrypt(byte[] src, byte[] password) {
try {
// 实例化
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));
byte[] result = cipher.doFinal(src);
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}
AES实现
import org.apache.commons.codec.binary.Hex;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
public class TestAES {
public static void main(String[] args) throws Exception {
String name = "hello word";
byte[] password = getPassword();
System.out.println("秘钥:" + Hex.encodeHexString(password));
byte[] encrypt = encrypt(name.getBytes(), password);
String encryptString = Hex.encodeHexString(encrypt);
System.out.println("秘钥加密后的密文:" + encryptString);
byte[] decodeHex = Hex.decodeHex(encryptString.toCharArray());
byte[] decrypt = decrypt(decodeHex, password);
System.out.println("秘钥解密后的明文:" + new String(decrypt));
}
/** * 获取随机秘钥 */
public static byte[] getPassword() throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
SecretKey secretKey = keyGenerator.generateKey();
byte[] keyEncoded = secretKey.getEncoded();
return keyEncoded;
}
/** * 获取专用密钥 */
private static Key getSecretKey(byte[] key) {
try {
return new SecretKeySpec(key, "AES");
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/** * 加密 */
public static byte[] encrypt(byte[] datasource, byte[] password) {
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
// 创建密码器
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));
// 初始化为加密模式的密码器
byte[] result = cipher.doFinal(datasource);// 加密
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/** * 解密 */
public static byte[] decrypt(byte[] src, byte[] password) {
try {
// 实例化
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));
byte[] result = cipher.doFinal(src);
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
PEB实现
import org.apache.commons.codec.binary.Hex;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.security.Key;
import java.security.SecureRandom;
public class TestPBE {
public static void main(String[] args) throws Exception {
String name = "hello word";
String password = "123456";
System.out.println("秘钥:" + password);
PBEParameterSpec salt = getSalt();
byte[] encrypt = encrypt(name.getBytes(), password, salt);
String encryptString = Hex.encodeHexString(encrypt);
System.out.println("秘钥加密后的密文:" + encryptString);
byte[] decrypt = decrypt(encrypt, password, salt);
System.out.println("秘钥解密后的明文:" + new String(decrypt));
}
/** * 获取专用密钥 */
private static Key getSecretKey(String password) {
try {
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHMD5andDES");
return factory.generateSecret(pbeKeySpec);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/** * 获取盐 */
private static PBEParameterSpec getSalt() {
SecureRandom secureRandom = new SecureRandom();
byte[] salt = secureRandom.generateSeed(8);
// 100次加盐迭代
return new PBEParameterSpec(salt, 100);
}
/** * 加密 */
public static byte[] encrypt(byte[] datasource, String password, PBEParameterSpec salt) {
try {
Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES");
// 创建密码器
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password), salt);
// 初始化为加密模式的密码器
byte[] result = cipher.doFinal(datasource);// 加密
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/** * 解密 */
public static byte[] decrypt(byte[] src, String password, PBEParameterSpec salt) {
try {
// 实例化
Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES");
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password), salt);
byte[] result = cipher.doFinal(src);
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}