Java密码学 | AI生成和翻译

Home 2025.03

Java 的 javax.crypto 包提供了一系列用于执行加密、解密、密钥生成和消息认证等密码学操作的类和方法。以下是一份关于如何使用 javax.crypto 的全面指南,包括对常见用例(如对称加密、非对称加密和消息认证)的解释和实际示例。


什么是 javax.crypto?

javax.crypto 包是 Java 密码学架构(JCA)的一部分,它提供了通过密码学实现安全通信的工具。它支持:

要使用 javax.crypto,你需要:

  1. 选择一个密码学算法。
  2. 生成或获取必要的密钥。
  3. 使用提供的类(例如 CipherKeyGeneratorMac)来执行操作。

以下是常见场景的逐步示例。


1. 使用 AES 进行对称加密

对称加密使用单个密钥进行加密和解密。以下是如何使用 Cipher 类,在 CBC 模式下使用 PKCS5 填充,通过 AES(高级加密标准)对字符串进行加密和解密。

步骤

示例代码

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.SecureRandom;
import java.nio.charset.StandardCharsets;

public class SymmetricEncryptionExample {
    public static void main(String[] args) throws Exception {
        // 步骤 1:为 AES 生成一个秘密密钥
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128); // 128 位密钥
        SecretKey secretKey = keyGen.generateKey();

        // 步骤 2:生成一个随机初始化向量(IV)
        SecureRandom random = new SecureRandom();
        byte[] iv = new byte[16]; // AES 块大小为 16 字节
        random.nextBytes(iv);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);

        // 步骤 3:创建并初始化用于加密的 Cipher
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);

        // 步骤 4:加密数据
        String plaintext = "Hello, World!";
        byte[] plaintextBytes = plaintext.getBytes(StandardCharsets.UTF_8);
        byte[] ciphertext = cipher.doFinal(plaintextBytes);

        // 步骤 5:使用相同的 IV 初始化用于解密的 Cipher
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
        byte[] decryptedBytes = cipher.doFinal(ciphertext);
        String decryptedText = new String(decryptedBytes, StandardCharsets.UTF_8);

        // 输出结果
        System.out.println("原始文本: " + plaintext);
        System.out.println("解密文本: " + decryptedText);
    }
}

关键点


2. 使用 RSA 进行非对称加密

非对称加密使用公钥加密,使用私钥解密。以下是一个使用 RSA 的示例。

步骤

示例代码

import javax.crypto.Cipher;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.nio.charset.StandardCharsets;

public class AsymmetricEncryptionExample {
    public static void main(String[] args) throws Exception {
        // 步骤 1:生成一个 RSA 密钥对
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        keyPairGen.initialize(2048); // 2048 位密钥
        KeyPair keyPair = keyPairGen.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        // 步骤 2:使用公钥加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        String plaintext = "Secret Message";
        byte[] plaintextBytes = plaintext.getBytes(StandardCharsets.UTF_8);
        byte[] ciphertext = cipher.doFinal(plaintextBytes);

        // 步骤 3:使用私钥解密
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(ciphertext);
        String decryptedText = new String(decryptedBytes, StandardCharsets.UTF_8);

        // 输出结果
        System.out.println("原始文本: " + plaintext);
        System.out.println("解密文本: " + decryptedText);
    }
}

关键点


3. 使用 HMAC 进行消息认证

消息认证码(MAC)确保数据的完整性和真实性。以下是如何使用 Mac 与 HMAC-SHA256。

示例代码

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class MacExample {
    public static void main(String[] args) throws Exception {
        // 步骤 1:创建一个秘密密钥
        String secret = "mysecretkey";
        SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");

        // 步骤 2:使用密钥初始化 Mac
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(secretKey);

        // 步骤 3:计算数据的 MAC
        String data = "Data to authenticate";
        byte[] macValue = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
        String macBase64 = Base64.getEncoder().encodeToString(macValue);

        // 输出结果
        System.out.println("MAC: " + macBase64);
    }
}

关键点


4. 加密/解密流

对于大型数据(例如文件),使用 CipherInputStreamCipherOutputStream

示例代码(加密文件)

import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.SecureRandom;

public class StreamEncryptionExample {
    public static void main(String[] args) throws Exception {
        // 生成密钥和 IV
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128);
        SecretKey secretKey = keyGen.generateKey();
        byte[] iv = new byte[16];
        new SecureRandom().nextBytes(iv);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);

        // 初始化 Cipher
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);

        // 加密文件
        try (FileInputStream fis = new FileInputStream("input.txt");
             FileOutputStream fos = new FileOutputStream("encrypted.txt");
             CipherOutputStream cos = new CipherOutputStream(fos, cipher)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                cos.write(buffer, 0, bytesRead);
            }
        }
    }
}

关键点


5. 基于密码的加密(PBE)

使用 SecretKeyFactory 从密码派生密钥。

示例代码

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.nio.charset.StandardCharsets;

public class PBEExample {
    public static void main(String[] args) throws Exception {
        // 密码和盐
        char[] password = "mysecretpassword".toCharArray();
        byte[] salt = new byte[16];
        new SecureRandom().nextBytes(salt);

        // 从密码派生密钥
        PBEKeySpec pbeKeySpec = new PBEKeySpec(password, salt, 10000, 256); // 256 位密钥
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        SecretKey tempKey = factory.generateSecret(pbeKeySpec);
        SecretKey secretKey = new SecretKeySpec(tempKey.getEncoded(), "AES");

        // 使用派生密钥加密
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        String plaintext = "Hello from PBE";
        byte[] ciphertext = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));

        System.out.println("加密后: " + Base64.getEncoder().encodeToString(ciphertext));
    }
}

关键点


javax.crypto 中的关键类


最佳实践


结论

要使用 javax.crypto,请根据你的需求选择合适的密码学算法,生成或获取密钥,并利用 CipherKeyGeneratorMac 等类来执行操作。无论是使用 AES 进行对称加密、使用 RSA 进行非对称加密,还是使用 HMAC 确保完整性,javax.crypto 都提供了相应的工具——结合适当的初始化和安全的密钥管理——可以在 Java 中实现强大的密码学功能。


Back Donate