常见加密算法梳理

常见加密算法梳理

  • 1. 前言
  • 2. 常见加密算法
    • 2.1. 散列算法(不可逆加密)
      • 2.1.1. MD5
      • 2.1.2. SHA-256
    • 2.2. 对称加密算法
      • 2.2.1. DES
      • 2.2.2. AES
    • 2.3. 非对称加密算法
      • 2.3.1. RSA
  • 3. 加密算法应用:Https

1. 前言

在当今的信息时代,数据的安全性显得尤为重要,加密算法作为保障数据安全的核心手段,在过去的几十年中经历了巨大的发展。信息加密前后端开发都经常需要使用到的技术,应用场景包括了数据存储、网络通信、身份认证等等,不同的应用场景也会需要使用到不同的签名加密算法,或者需要搭配不一样的签名加密算法来达到业务目标。这里简单的给大家介绍几种常见的签名加密算法和一些典型场景下的应用。

2. 常见加密算法

常见加密算法梳理_第1张图片

2.1. 散列算法(不可逆加密)

2.1.1. MD5

MD5是一种广泛使用的散列算法,产生一个128位哈希值。它通常用于验证数据的完整性和一致性,但由于存在碰撞攻击,现在被认为不够安全(攻击者可以通过暴力破解或彩虹表攻击等方式破解),虽然可以通过加盐,也就是对在原文里再加上一些不固定的字符串来缓解,但是完全可以用更安全的SHA系列算法替代

public class MD5 {
    private static final String MD5_ALGORITHM = "MD5";
    public static String encrypt(String data) throws Exception {
        // 获取MD5算法实例
        MessageDigest messageDigest = MessageDigest.getInstance(MD5_ALGORITHM);
        // 计算散列值
        byte[] digest = messageDigest.digest(data.getBytes());
        Formatter formatter = new Formatter();
        // 补齐前导0,并格式化
        for (byte b : digest) {
            formatter.format("%02x", b);
        }
        return formatter.toString();
    }
 
    public static void main(String[] args) throws Exception {
        String data = "Hello World";
        String encryptedData = encrypt(data);
        System.out.println("加密后的数据:" + encryptedData);
    }
}

2.1.2. SHA-256

  • SHA(Secure Hash Algorithm)系列算法是一组密码散列函数,用于将任意长度的数据映射为固定长度的散列值。SHA系列算法由美国国家安全局(NSA)1993年设计,目前共有SHA-1(存在缺陷,不推荐使用)SHA-2SHA-3三种版本
  • SHA-2算法包括SHA-224SHA-256SHA-384SHA-512四种散列函数,分别将任意长度的数据映射为224位256位384位512位的散列值
public class SHA256 {
    private static final String SHA_256_ALGORITHM = "SHA-256";
    public static String encrypt(String data) throws Exception {
        //获取SHA-256算法实例
        MessageDigest messageDigest = MessageDigest.getInstance(SHA_256_ALGORITHM);
        //计算散列值
        byte[] digest = messageDigest.digest(data.getBytes());
        StringBuilder stringBuilder = new StringBuilder();
        //将byte数组转换为15进制字符串
        for (byte b : digest) {
            stringBuilder.append(Integer.toHexString((b & 0xFF) | 0x100), 1, 3);
        }
        return stringBuilder.toString();
    }
 
    public static void main(String[] args) throws Exception {
        String data = "Hello World";
        String encryptedData = encrypt(data);
        System.out.println("加密后的数据:" + encryptedData);
    }
}

SHA-2算法之所以比MD5强,主要有两个原因:

  • 散列值长度更长:例如SHA-256算法的散列值长度为256位,而MD5算法的散列值长度为128位,这就提高了攻击者暴力破解或者彩虹表攻击的难度
  • 更强的碰撞抗性:SHA算法采用了更复杂的运算过程和更多的轮次,使得攻击者更难以通过预计算或巧合找到碰撞,但是实际应用中加盐还是必不可少的

2.2. 对称加密算法

对称加密算法,使用同一个密钥进行加密和解密
常见加密算法梳理_第2张图片

  • 加密和解密过程使用的是相同的密钥,因此密钥的安全性至关重要。如果密钥泄露,攻击者可以轻易地破解加密数据
  • 常见的对称加密算法包括DES3DESAES等。其中,AES算法是目前使用最广泛的对称加密算法之一,具有比较高的安全性和加密效率
    • AES(高级加密标准):AES是一种常用的对称加密算法,被广泛用于政府和商业领域的数据加密。它采用固定长度的明文块和密钥进行加密,提供128位192位256位三种加密强度
    • DES(数据加密标准):DES是一种较旧的对称加密算法,使用56位密钥和8字节的块大小。由于其密钥长度较短,现在已被认为不够安全,已被AES取代
    • 3DES(三重数据加密算法):3DES是对DES的一种扩展,通过使用三个DES密钥进行三次加密来提供更高的安全性

2.2.1. DES

DES算法使用56位密钥对数据进行加密,加密过程中使用了置换、替换、异或等运算,具有较高的安全性,但是这也是过去式了,由于密匙过短,还是比较容易被暴力破解的

public class DES {
    private static final String DES_ALGORITHM = "DES";
 
    /**
     * DES加密
     *
     * @param data 待加密的数据
     * @param key  密钥,长度必须为8位
     * @return 加密后的数据,使用Base64编码
     */
    public static String encrypt(String data, String key) throws Exception {
        // 根据密钥生成密钥规范
        KeySpec keySpec = new DESKeySpec(key.getBytes());
        // 根据密钥规范生成密钥工厂
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);
        // 根据密钥工厂和密钥规范生成密钥
        SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
 
        // 根据加密算法获取加密器
        Cipher cipher = Cipher.getInstance(DES_ALGORITHM);
        // 初始化加密器,设置加密模式和密钥
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        // 加密数据
        byte[] encryptedData = cipher.doFinal(data.getBytes());
        // 对加密后的数据进行Base64编码
        return Base64.getEncoder().encodeToString(encryptedData);
    }
 
    /**
     * DES解密
     *
     * @param encryptedData 加密后的数据,使用Base64编码
     * @param key           密钥,长度必须为8位
     * @return 解密后的数据
     */
    public static String decrypt(String encryptedData, String key) throws Exception {
        // 根据密钥生成密钥规范
        KeySpec keySpec = new DESKeySpec(key.getBytes());
        // 根据密钥规范生成密钥工厂
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);
        // 根据密钥工厂和密钥规范生成密钥
        SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
 
        // 对加密后的数据进行Base64解码
        byte[] decodedData = Base64.getDecoder().decode(encryptedData);
        // 根据加密算法获取解密器
        Cipher cipher = Cipher.getInstance(DES_ALGORITHM);
        // 初始化解密器,设置解密模式和密钥
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        // 解密数据
        byte[] decryptedData = cipher.doFinal(decodedData);
        // 将解密后的数据转换为字符串
        return new String(decryptedData);
    }
 
    public static void main(String[] args) throws Exception {
        String data = "Hello World";
        String key = "12345678"; 
 
        String encryptedData = encrypt(data, key);
        System.out.println("加密后的数据:" + encryptedData);
 
        String decryptedData = decrypt(encryptedData, key);
        System.out.println("解密后的数据:" + decryptedData);
    }
}

2.2.2. AES

AES(Advanced Encryption Standard)即高级加密标准,是一种对称加密算法,被广泛应用于数据加密和保护领域。AES算法使用的密钥长度为128位192位256位,比DES算法的密钥长度更长,安全性更高

public class AES {
    private static final String AES_ALGORITHM = "AES";
    // AES加密模式为CBC,填充方式为PKCS5Padding
    private static final String AES_TRANSFORMATION = "AES/CBC/PKCS5Padding";
    // AES密钥为16位
    private static final String AES_KEY = "1234567890123456";
    // AES初始化向量为16位
    private static final String AES_IV = "abcdefghijklmnop";
 
    /**
     * AES加密
     *
     * @param data 待加密的数据
     * @return 加密后的数据,使用Base64编码
     */
    public static String encrypt(String data) throws Exception {
        // 将AES密钥转换为SecretKeySpec对象
        SecretKeySpec secretKeySpec = new SecretKeySpec(AES_KEY.getBytes(), AES_ALGORITHM);
        // 将AES初始化向量转换为IvParameterSpec对象
        IvParameterSpec ivParameterSpec = new IvParameterSpec(AES_IV.getBytes());
        // 根据加密算法获取加密器
        Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
        // 初始化加密器,设置加密模式、密钥和初始化向量
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
        // 加密数据
        byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        // 对加密后的数据使用Base64编码
        return Base64.getEncoder().encodeToString(encryptedData);
    }
 
    /**
     * AES解密
     *
     * @param encryptedData 加密后的数据,使用Base64编码
     * @return 解密后的数据
     */
    public static String decrypt(String encryptedData) throws Exception {
        // 将AES密钥转换为SecretKeySpec对象
        SecretKeySpec secretKeySpec = new SecretKeySpec(AES_KEY.getBytes(), AES_ALGORITHM);
        // 将AES初始化向量转换为IvParameterSpec对象
        IvParameterSpec ivParameterSpec = new IvParameterSpec(AES_IV.getBytes());
        // 根据加密算法获取解密器
        Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
        // 初始化解密器,设置解密模式、密钥和初始化向量
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        // 对加密后的数据使用Base64解码
        byte[] decodedData = Base64.getDecoder().decode(encryptedData);
        // 解密数据
        byte[] decryptedData = cipher.doFinal(decodedData);
        // 返回解密后的数据
        return new String(decryptedData, StandardCharsets.UTF_8);
    }
 
    public static void main(String[] args) throws Exception {
        String data = "Hello World";
 
        String encryptedData = encrypt(data);
        System.out.println("加密后的数据:" + encryptedData);
 
        String decryptedData = decrypt(encryptedData);
        System.out.println("解密后的数据:" + decryptedData);
    }
}

2.3. 非对称加密算法

非对称加密算法是指加密和解密使用不同密钥的加密算法,但是相互匹配,一个称为公钥,另一个称为私钥。使用其中的一个加密,则使用另一个进行解密,例如使用公钥加密,则需要使用私钥解密
常见加密算法梳理_第3张图片

2.3.1. RSA

public class RSA {
    private static final String RSA_ALGORITHM = "RSA";
 
    /**
     * 生成RSA密钥对
     *
     * @return RSA密钥对
     */
    public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA_ALGORITHM);
        keyPairGenerator.initialize(2048); // 密钥大小为2048位
        return keyPairGenerator.generateKeyPair();
    }
 
    /**
     * 使用公钥加密数据
     *
     * @param data      待加密的数据
     * @param publicKey 公钥
     * @return 加密后的数据
     */
    public static String encrypt(String data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedData);
    }
 
    /**
     * 使用私钥解密数据
     *
     * @param encryptedData 加密后的数据
     * @param privateKey    私钥
     * @return 解密后的数据
     */
    public static String decrypt(String encryptedData, PrivateKey privateKey) throws Exception {
        byte[] decodedData = Base64.getDecoder().decode(encryptedData);
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedData = cipher.doFinal(decodedData);
        return new String(decryptedData, StandardCharsets.UTF_8);
    }
 
    public static void main(String[] args) throws Exception {
        KeyPair keyPair = generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
 
        String data = "Hello World";
 
        String encryptedData = encrypt(data, publicKey);
        System.out.println("加密后的数据:" + encryptedData);
 
        String decryptedData = decrypt(encryptedData, privateKey);
        System.out.println("解密后的数据:" + decryptedData);
    }
}
  • RSA算法的优点是安全性高,公钥可以公开,私钥必须保密,保证了数据的安全性;可用于数字签名、密钥协商等多种应用场景
  • 缺点是加密、解密速度较慢,密钥长度越长,加密、解密时间越长;密钥长度过短容易被暴力破解,密钥长度过长则会增加计算量和存储空间的开销

3. 加密算法应用:Https

常见加密算法梳理_第4张图片HTTPS加密解密流程:

  1. 客户端发起HTTPS请求:用户使用浏览器输入网址访问HTTPS站点,准备发起HTTPS请求
  2. 服务端提供证书:服务器返回公钥证书,证书包含了服务器的公钥颁发者(证书颁发机构)等信息
  3. 客户端验证证书:浏览器验证证书的有效性、合法性、来源等,校验证书的过程用到了非对称加密散列算法
    • 客户端使用证书颁发机构公钥对证书进行验证,保证证书的真实性和合法性
    • 客户端使用证书中的公钥服务端的数字签名进行验证,保证服务器的身份和数据的完整性
    • 客户端使用散列算法计算出散列值,和证书种的散列值进行对比,保证证书的完整性
  4. 客户端生成对称密钥:客户端生成一个随机数,作为对称密钥
  5. 对称密钥加密传输:客户端使用服务器的公钥对随机数进行加密,然后将加密后的信息传输给服务器
  6. 服务端获取对称密钥:服务端使用私钥解密(客户端公钥加密、服务器私钥解密)客户端发送的对称密钥,得到对称密钥
  7. 客户端与服务器使用对称密钥进行通信:服务器与浏览器都使用对称密钥对数据进行加密和解密,以此确保数据传输的安全性

在数据传输的过程中,也用到了散列算法:

  • 消息摘要:在数据传输过程中,客户端和服务器都使用散列算法计算消息的散列值,对方收到消息后,会对散列值进行比较,确保传输数据的完整性

你可能感兴趣的:(java基础,java,开发语言)