杰瑞科技汇

js des加密 java解密

核心要点

  1. DES 算法:这是一种对称加密算法,加密和解密使用相同的密钥。
  2. 工作模式:DES 通常与某种“工作模式”一起使用,最常见的是 ECB (Electronic Codebook)CBC (Cipher Block Chaining)强烈推荐使用 CBC 模式,因为它比 ECB 更安全,本示例将重点展示 CBC 模式。
  3. 填充方式:DES 要求数据长度是 8 字节的整数倍,如果原始数据不是,就需要进行填充,最常用的填充方式是 PKCS5PaddingPKCS7Padding(两者在 DES 中效果相同)。
  4. IV (Initialization Vector - 初始化向量):在使用 CBC 模式时,需要一个初始化向量,IV 不需要保密,但它必须是随机的,并且与密钥一同使用,以确保即使对相同的数据加密多次,结果也不同。
  5. 编码格式:加密后的结果是二进制数据(字节数组),不能直接作为文本传输,必须将其转换为一种文本编码格式,最常用的是 Base64,前端和后端都需要使用相同的 Base64 编码/解码库。

第一步:前端 JavaScript 加密

我们将使用 crypto-js 这个流行的库,因为它提供了与 Java 标准库兼容的默认选项。

js des加密 java解密-图1
(图片来源网络,侵删)

引入 Crypto-JS

在你的 HTML 文件中,通过 CDN 引入:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">JS DES 加密示例</title>
    <!-- 引入 crypto-js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
</head>
<body>
    <h1>前端 DES 加密</h1>
    <script>
        // --- 你的配置 ---
        const secretKey = "12345678"; // DES 密钥,必须是8字节
        const iv = "87654321";        // 初始化向量,必须是8字节
        const plaintext = "这是一段需要加密的敏感信息,Hello, World!";
        // --- 加密过程 ---
        console.log("原始明文:", plaintext);
        // 1. 创建加密器配置对象
        // Crypto-js 的 DES 默认使用 ECB 模式和 PKCS7 填充。
        // 为了匹配 Java 的 CBC 模式,我们需要明确指定。
        const key = CryptoJS.enc.Utf8.parse(secretKey);
        const iv_wordArray = CryptoJS.enc.Utf8.parse(iv);
        // 2. 执行加密
        const encrypted = CryptoJS.DES.encrypt(plaintext, key, {
            iv: iv_wordArray,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        });
        // 3. 将结果转换为 Base64 字符串
        const encryptedBase64 = encrypted.toString();
        console.log("加密后的 Base64:", encryptedBase64);
        // --- 解密过程 (用于验证) ---
        const decrypted = CryptoJS.DES.decrypt(encryptedBase64, key, {
            iv: iv_wordArray,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        });
        const originalText = decrypted.toString(CryptoJS.enc.Utf8);
        console.log("解密后的明文:", originalText);
    </script>
</body>
</html>

代码解释:

  • secretKeyiv:必须都是 8个字符,在真实项目中,密钥应该通过安全的方式传递,而不是硬编码。
  • CryptoJS.enc.Utf8.parse():将字符串(UTF-8 编码)转换为 CryptoJS 库内部使用的 WordArray 对象。
  • CryptoJS.DES.encrypt():核心加密函数。
    • 第一个参数:要加密的明文。
    • 第二个参数:密钥 WordArray。
    • 第三个参数:配置对象,关键点
      • iv: 初始化向量。
      • mode: 设置为 CryptoJS.mode.CBC
      • padding: 设置为 CryptoJS.pad.Pkcs7
  • encrypted.toString():将加密结果(一个 CipherParams 对象)转换为 Base64 字符串,方便网络传输。

第二步:后端 Java 解密

我们将使用 Java 标准库 javax.crypto 来实现解密,这与 crypto-js 的默认设置完美兼容。

Java 解密代码

创建一个 Java 类,DesDecryptor.java

js des加密 java解密-图2
(图片来源网络,侵删)
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class DesDecryptor {
    // --- 你的配置 (必须与 JS 端完全一致) ---
    private static final String SECRET_KEY = "12345678"; // DES 密钥,必须是8字节
    private static final String INIT_VECTOR = "87654321"; // 初始化向量,必须是8字节
    public static void main(String[] args) {
        // 从前端获取到的加密后的 Base64 字符串
        // 你可以把 JS 控制台打印的值复制到这里
        String encryptedBase64FromJs = "Q1x8mJ3z4yK5uP6v+8wA7bC9dD0eF1gH2iJ3kL4mN5oP6qR7sT8uV9wX0yZ1aB2cD3eF4gH5iJ6kL7mN8oP9qR0sT1uV2wX3yZ4aB5cD6eF7gH8iJ9kL0mN1oP2qR3sT4uV5wX6yZ7aB8cD9eF0gH1iJ2kL3mN4oP5qR6sT7uV8wX9yZ0aB1cD2eF3gH4iJ5kL6mN7oP8qR9sT0uV1wX2yZ3aB4cD5eF6gH7iJ8kL9mN0oP1qR2sT3uV4wX5yZ6aB7cD8eF9gH0iJ1kL2mN3oP4qR5sT6uV7wX8yZ9aB0cD1eF2gH3iJ4kL5mN6oP7qR8sT9uV0wX1yZ2aB3cD4eF5gH6iJ7kL8mN9oP0qR1sT2uV3wX4yZ5aB6cD7eF8gH9iJ0kL1mN2oP3qR4sT5uV6wX7yZ8aB9cD0eF1gH2iJ3kL4mN5oP6qR7sT8uV9wX0yZ1";
        try {
            String decryptedText = decrypt(encryptedBase64FromJs);
            System.out.println("解密成功!");
            System.out.println("解密后的明文: " + decryptedText);
        } catch (Exception e) {
            System.err.println("解密失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
    public static String decrypt(String encryptedBase64) throws Exception {
        // 1. 创建密钥规范和 IV 规范
        // SecretKeySpec 用于指定密钥
        IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes(StandardCharsets.UTF_8));
        SecretKeySpec skeySpec = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), "DES");
        // 2. 创建 Cipher 实例
        // "DES/CBC/PKCS5Padding" 是关键,必须与 JS 端的配置完全对应
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        // 3. 初始化 Cipher 为解密模式
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        // 4. 解码 Base64 字符串为字节数组
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedBase64);
        // 5. 执行解密
        byte[] originalBytes = cipher.doFinal(encryptedBytes);
        // 6. 将解密后的字节数组转换为 UTF-8 字符串
        return new String(originalBytes, StandardCharsets.UTF_8);
    }
}

代码解释:

  • 配置SECRET_KEYINIT_VECTOR 必须和 JavaScript 中的完全一样。
  • new IvParameterSpec(...)new SecretKeySpec(...):将字符串转换为 Java 加密库所需的规范对象。
  • Cipher.getInstance("DES/CBC/PKCS5Padding"):这是最关键的一步。
    • DES: 指定算法。
    • CBC: 指定工作模式,必须与 JS 端的 CryptoJS.mode.CBC 对应。
    • PKCS5Padding: 指定填充方式,必须与 JS 端的 CryptoJS.pad.Pkcs7 对应。
  • cipher.init(Cipher.DECRYPT_MODE, ...):初始化 Cipher 对象,设置为解密模式。
  • Base64.getDecoder().decode(...):将前端传来的 Base64 字符串解码回原始的字节数组。
  • cipher.doFinal(...):执行实际的解密操作。
  • new String(..., StandardCharsets.UTF_8):将解密后的字节数组转换回可读的字符串。

运行与验证

  1. 运行前端:将 HTML 文件在浏览器中打开,打开开发者工具的控制台,你会看到类似下面的输出:
    原始明文: 这是一段需要加密的敏感信息,Hello, World!
    加密后的 Base64: Q1x8mJ3z4yK5uP6v+8wA7bC9dD0eF1gH2iJ3kL4mN5oP6qR7sT8uV9wX0yZ1aB2cD3eF4gH5iJ6kL7mN8oP9qR0sT1uV2wX3yZ4aB5cD6eF7gH8iJ9kL0mN1oP2qR3sT4uV5wX6yZ7aB8cD9eF0gH1iJ2kL3mN4oP5qR6sT7uV8wX9yZ0aB1cD2eF3gH4iJ5kL6mN7oP8qR9sT0uV1wX2yZ3aB4cD5eF6gH7iJ8kL9mN0oP1qR2sT3uV4wX5yZ6aB7cD8eF9gH0iJ1kL2mN3oP4qR5sT6uV7wX8yZ9aB0cD1eF2gH3iJ4kL5mN6oP7qR8sT9uV0wX1yZ2aB3cD4eF5gH6iJ7kL8mN9oP0qR1sT2uV3wX4yZ5aB6cD7eF8gH9iJ0kL1mN2oP3qR4sT5uV6wX7yZ8aB9cD0eF1gH2iJ3kL4mN5oP6qR7sT8uV9wX0yZ1
    解密后的明文: 这是一段需要加密的敏感信息,Hello, World!
  2. 复制 Base64:复制 加密后的 Base64 字符串。
  3. 运行后端:将复制的 Base64 字符串粘贴到 Java 代码的 encryptedBase64FromJs 变量中,然后运行 main 方法。
  4. 检查结果:控制台应该会输出:
    解密成功!
    解密后的明文: 这是一段需要加密的敏感信息,Hello, World!

如果前后端输出的明文完全一致,那么恭喜你,你已经成功实现了 JS DES 加密和 Java 解密!

安全性提醒

  • DES 已不安全:DES 算法的密钥长度只有 56 位,在现代计算能力下非常容易被暴力破解。在生产环境中,强烈建议使用更安全的算法,如 AES (Advanced Encryption Standard)
  • 密钥管理:示例中的密钥是硬编码的,这是非常危险的做法,在实际应用中,密钥应该通过安全的渠道(如密钥管理服务 KMS)进行分发和管理,并且不应该在代码或前端中暴露。
js des加密 java解密-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇