对称加密算法原理与常用实现

目录

  • 定义
  • 常用对称加密算法
      • 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;
    }

你可能感兴趣的:(安全)