五种常见的加密算法,建议掌握!

安全 数据安全
本文我们分析了五种常见的加密算法,不同的加密方式各有优缺点,适用于不同的应用场景。

在实际工作中,对于数据保护、身份验证、通信安全这些有数据安全的场景,我们通常会对数据进行加密。那么,常用的加密技术有哪些?它们有什么优缺点?我们该如何选择?这篇文章我们来聊一聊 5种常见的加密算法。

1. 对称加密

对称加密(Symmetric Encryption)是工作中比较常见的一种基于密钥的加密技术,它的特点就是使用相同的密钥进行加密和解密,算法简单高效。

对称加密常见的算法:

  • AES(高级加密标准):目前最广泛使用的对称加密算法,具有高安全性和高效性。
  • DES(数据加密标准):较早的对称加密算法,因安全性较低现已较少使用。
  • 3DES(Triple DES):对DES算法的改进,通过三次加密提高安全性。
  • Blowfish、Twofish:适用于不同应用场景的灵活对称加密算法。

优点:

  • 高安全性,被广泛认可和使用。
  • 支持多种密钥长度(128、192、256位)。
  • 加解密速度快,适合大数据量加密。

缺点:

  • 密钥分发问题,需确保密钥在发送方和接收方之间安全传输。
  • 不适合加密少量数据或需要频繁修改密钥的场景。

使用场景:

  • 数据存储加密:如磁盘加密(BitLocker、FileVault)、数据库加密,确保存储在磁盘或数据库中的数据不被未授权访问。
  • 通信加密:用于VPN、TLS/SSL协议中的数据传输加密,保障网络通信的机密性和完整性。
  • 应用程序加密:保护应用程序内部的数据,如配置文件、缓存数据等。

Java示例:

以下的示例展示了如何使用 Java实现AES 加密与解密。

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

publicclass AESDemo {
    // 生成AES密钥
    public static SecretKey generateAESKey(int n) throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(n); // 128, 192, or 256
        return keyGen.generateKey();
    }

    // 加密
    public static String encrypt(String data, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encrypted = cipher.doFinal(data.getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(encrypted);
    }

    // 解密
    public static String decrypt(String encryptedData, SecretKey key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decodedBytes = Base64.getDecoder().decode(encryptedData);
        byte[] decrypted = cipher.doFinal(decodedBytes);
        returnnew String(decrypted, "UTF-8");
    }

    public static void main(String[] args) throws Exception {
        String originalText = "Hello, AES Encryption!";
        SecretKey secretKey = generateAESKey(128);

        String encryptedText = encrypt(originalText, secretKey);
        System.out.println("Encrypted: " + encryptedText);

        String decryptedText = decrypt(encryptedText, secretKey);
        System.out.println("Decrypted: " + decryptedText);
    }
}

2. 非对称加密

非对称加密(Asymmetric Encryption)是对称加密的一个升级版本,不再使用相同的秘密,而是使用了一对密钥——公钥和私钥。公钥用于加密,私钥用于解密,密钥之间数学相关但无法从公钥轻易推导出私钥。

非对称加密的常见算法:

  • RSA:广泛应用的非对称加密算法,适用于数据加密和数字签名。
  • ECC(椭圆曲线加密):在相同安全水平下具有更短密钥长度,效率更高,适用于移动设备和嵌入式系统。
  • DSA(数字签名算法):主要用于数字签名,确保数据的完整性和来源。

使用场景:

  • 安全通信:用于SSL/TLS协议中的密钥交换,确保双方通信的安全性。
  • 数字签名:验证数据的来源和完整性,如电子邮件签名、代码签名、文件签名等。
  • 身份验证:在身份验证系统中,使用公钥基础设施(PKI)进行用户身份验证和授权。

Java示例:

以下的示例展示了如何使用 Java实现RSA 加密与解密。

import java.security.*;
import javax.crypto.Cipher;
import java.util.Base64;

publicclass RSADemo {
    // 生成RSA密钥对
    public static KeyPair generateRSAKeyPair(int keySize) throws NoSuchAlgorithmException {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(keySize, new SecureRandom());
        return keyGen.generateKeyPair();
    }

    // 使用RSA公钥加密
    public static String encrypt(String data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); // 使用OAEP填充
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    // 使用RSA私钥解密
    public static String decrypt(String encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); // 使用OAEP填充
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
        returnnew String(decryptedBytes, "UTF-8");
    }

    public static void main(String[] args) {
        try {
            String originalText = "Hello, This is RSA Encryption!";
            // 生成RSA密钥对
            KeyPair keyPair = generateRSAKeyPair(2048);

            // 加密
            String encryptedText = encrypt(originalText, keyPair.getPublic());
            System.out.println("Encrypted (RSA): " + encryptedText);

            // 解密
            String decryptedText = decrypt(encryptedText, keyPair.getPrivate());
            System.out.println("Decrypted (RSA): " + decryptedText);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

注意: 在实际应用中,建议使用更为安全的填充模式(如OAEP),而不是简单的PKCS#1填充。

3. 哈希函数

哈希函数(Hash Functions)是将任意长度的输入数据映射为固定长度的哈希值,且具有单向性(不可逆)和抗碰撞性(难以找到不同输入具有相同哈希值)。比如工作中,我们会生成一个全局ID,然后通过哈希算法进行压缩。

哈希算法常见的算法:

  • SHA-256、SHA-3:广泛用于数据完整性验证和区块链技术。
  • MD5、SHA-1:由于安全性问题逐渐被淘汰,但仍在某些遗留系统中使用。

使用场景:

  • 数据完整性验证:通过比较哈希值确保数据在传输或存储过程中未被篡改。
  • 密码存储:将用户密码进行哈希存储,增加密码泄露后的安全性(通常结合加盐技术)。
  • 数字签名:在签名过程中,先对数据进行哈希,再对哈希值进行加密,提高效率和安全性。

Java 示例代码

下面给出了一个基于 SHA-256 哈希函数的示例:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

publicclass SHADemo {
    public static String hashSHA256(String data) throws NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hashBytes = digest.digest(data.getBytes());

        // 转换为十六进制字符串
        StringBuilder sb = new StringBuilder();
        for (byte b : hashBytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    public static void main(String[] args) throws Exception {
        String originalText = "Hello, SHA-256 Hash!";
        String hash = hashSHA256(originalText);
        System.out.println("SHA-256 Hash: " + hash);
    }
}

4. 量子加密

量子加密(Quantum Encryption)主要指基于量子力学原理的加密技术,其中最著名的是量子密钥分发(Quantum Key Distribution, QKD)。QKD利用量子态的不可克隆性和测量的扰动性,确保密钥在传输过程中绝对安全,即使面临具备量子计算能力的攻击者。

在普通的开发中一般很少用到这个算法,但是信息安全领域比较常见。

量子加密常见技术:

  • 量子密钥分发(QKD):通过量子态传输密钥,确保密钥交换过程的安全性。

使用场景:

  • 高安全需求的通信:政府、军事和金融机构等需要最高级别安全保护的通信领域。
  • 未来网络安全:为应对量子计算机对现有加密算法的威胁,量子加密技术正逐步研究和应用。

Java示例:

下面的示例,我们使用 Java模拟BB84协议。主要步骤说明如下:

  • Alice生成比特和基: 随机生成一串比特(0或1)和对应的基("+"或"×")。
  • Bob测量比特: 对每个接收到的比特,Bob随机选择一个基进行测量。如果Alice和Bob的基相同,Bob测量结果应与Alice的比特相同;否则,测量结果是随机的。
  • 基匹配与密钥生成: Alice和Bob共享基信息,并保留基相同的比特作为密钥。
  • 安全性检测: 随机抽取部分密钥进行比对,判断是否存在窃听。
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

publicclass BB84Demo {
    public static void main(String[] args) {
        int keyLength = 100; // 初始密钥长度
        double eavesdropProb = 0.05; // 窃听概率,即Eve拦截的比特比例

        // Alice生成随机比特和基
        List<Integer> aliceBits = generateRandomBits(keyLength);
        List<Character> aliceBases = generateRandomBases(keyLength);

        // Eve可能窃听部分比特
        List<Integer> eavesdroppedBits = new ArrayList<>();
        List<Character> eavesdroppedBases = new ArrayList<>();
        Random rand = new Random();
        for (int i = 0; i < keyLength; i++) {
            if (rand.nextDouble() < eavesdropProb) {
                // Eve窃听
                char eBase = rand.nextBoolean() ? '+' : '×';
                eavesdroppedBases.add(eBase);
                // 如果Eve的基与Alice相同,Eve获取正确的比特;否则,Eve随机比特
                if (eBase == aliceBases.get(i)) {
                    eavesdroppedBits.add(aliceBits.get(i));
                } else {
                    eavesdroppedBits.add(rand.nextBoolean() ? 1 : 0);
                }
            } else {
                eavesdroppedBits.add(null); // 没有窃听
            }
        }

        // Bob接收量子比特,进行测量
        List<Integer> bobBits = new ArrayList<>();
        List<Character> bobBases = generateRandomBases(keyLength);
        for (int i = 0; i < keyLength; i++) {
            char bBase = bobBases.get(i);
            if (eavesdroppedBits.get(i) != null) {
                // 如果Eve窃听了这个比特,Bob的测量可能受到影响
                if (bBase == aliceBases.get(i)) {
                    bobBits.add(eavesdroppedBits.get(i));
                } else {
                    bobBits.add(rand.nextBoolean() ? 1 : 0);
                }
            } else {
                // 没有被窃听
                if (bBase == aliceBases.get(i)) {
                    bobBits.add(aliceBits.get(i));
                } else {
                    bobBits.add(rand.nextBoolean() ? 1 : 0);
                }
            }
        }

        // Alice和Bob公开基,保留基相同的比特
        List<Integer> aliceKey = new ArrayList<>();
        List<Integer> bobKey = new ArrayList<>();
        for (int i = 0; i < keyLength; i++) {
            if (aliceBases.get(i).equals(bobBases.get(i))) {
                aliceKey.add(aliceBits.get(i));
                bobKey.add(bobBits.get(i));
            }
        }

        System.out.println("Alice的初始比特序列: " + aliceBits);
        System.out.println("Alice的基序列: " + aliceBases);
        System.out.println("Bob的基序列: " + bobBases);
        System.out.println("Eve窃听的比特序列: " + eavesdroppedBits);
        System.out.println("Alice和Bob共享的密钥长度: " + aliceKey.size());

        // 安全性检测:随机抽取部分密钥进行比对
        int testSize = Math.min(10, aliceKey.size()); // 抽取10个比特进行测试
        List<Integer> aliceTest = new ArrayList<>();
        List<Integer> bobTest = new ArrayList<>();
        Random testRand = new Random();
        List<Integer> indices = new ArrayList<>();
        while (indices.size() < testSize) {
            int index = testRand.nextInt(aliceKey.size());
            if (!indices.contains(index)) {
                indices.add(index);
                aliceTest.add(aliceKey.get(index));
                bobTest.add(bobKey.get(index));
            }
        }

        System.out.println("Alice的测试比特: " + aliceTest);
        System.out.println("Bob的测试比特: " + bobTest);

        // 计算错误率
        int errorCount = 0;
        for (int i = 0; i < testSize; i++) {
            if (!aliceTest.get(i).equals(bobTest.get(i))) {
                errorCount++;
            }
        }
        double errorRate = (double) errorCount / testSize;
        System.out.printf("测试错误率: %.2f%%\n", errorRate * 100);

        if (errorRate > 0.1) { // 假设错误率大于10%认为存在窃听
            System.out.println("检测到潜在的窃听行为,放弃当前密钥并重新生成。");
        } else {
            // 移除测试比特后,剩余的密钥作为最终共享密钥
            List<Integer> finalKey = aliceKey.stream()
                    .collect(Collectors.toList());
            for (int index : indices) {
                finalKey.set(index, null);
            }
            finalKey = finalKey.stream().filter(bit -> bit != null).collect(Collectors.toList());
            System.out.println("最终共享的密钥: " + finalKey);
        }
    }

    // 生成随机比特序列
    public static List<Integer> generateRandomBits(int length) {
        List<Integer> bits = new ArrayList<>(length);
        Random rand = new Random();
        for (int i = 0; i < length; i++) {
            bits.add(rand.nextBoolean() ? 1 : 0);
        }
        return bits;
    }

    // 生成随机基序列
    public static List<Character> generateRandomBases(int length) {
        List<Character> bases = new ArrayList<>(length);
        Random rand = new Random();
        for (int i = 0; i < length; i++) {
            bases.add(rand.nextBoolean() ? '+' : '×');
        }
        return bases;
    }
}

5. 混合加密

混合加密(Hybrid Encryption),顾名思义,就是将多种加密算法混合使用。比如将对称加密和非对称加密混合,先使用非对称加密交换对称加密的会话密钥,再使用对称加密进行数据传输。

使用场景:

  • SSL/TLS协议:在建立安全连接时,利用非对称加密进行密钥交换,随后使用对称加密进行数据传输,兼顾安全性和效率。
  • 加密通信工具:如PGP(Pretty Good Privacy),用于加密电子邮件和文件传输。

总结

本文,我们分析了五种常见的加密算法:

  • 对称加密
  • 非对称加密
  • Hash算法
  • 量子加密
  • 混合加密

不同的加密方式各有优缺点,适用于不同的应用场景。在实际工作中,我们在使用这些加密算法时一定要特别注意其优缺点,同时也需要关注实现的复杂度。

责任编辑:赵宁宁 来源: 猿java
相关推荐

2024-04-28 11:22:18

2020-05-08 11:13:28

Python数据技术

2024-07-12 11:54:38

2020-05-09 14:20:11

信息安全加密

2022-06-27 18:54:54

Python爬虫加密算法

2021-04-15 09:02:33

Python加密解密

2023-10-16 19:05:20

2012-09-13 09:58:38

2020-12-16 05:46:58

算法加密算法MD5

2021-11-22 23:20:01

加密算法架构

2023-08-02 07:27:53

2022-11-09 08:24:39

2010-09-09 10:06:56

Zigbee协议栈加密算法

2009-08-13 18:12:11

C#数据加密

2015-06-02 10:15:08

2024-12-31 08:00:00

SpringBoot开发加密

2023-07-30 17:44:24

CryptoJS加密字符串

2011-08-18 12:12:29

2009-08-21 15:02:31

C#加密算法

2015-05-11 10:40:08

加密数字图像加密加密算法
点赞
收藏

51CTO技术栈公众号