目录
- 定义
- 常用对称加密算法
- DES
- 3DES
- AES
- PEB
- 常用对称加密算法的java实现
- DES实现
- 3DES实现
- AES实现
- PEB实现
定义
原文通过加密秘钥生成密文,密文通过解密秘钥得到原文。
对于加密秘钥和解密秘钥是相同的算法,就叫对称加密算法。
常用对称加密算法
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;}