Java javax.crypto加密技术详解与实战代码示例

2024-06-21 李腾 81 次阅读 0 次点赞
本文全面介绍Java密码学扩展包javax.crypto的核心功能,详细解析Cipher、KeyGenerator、KeyPairGenerator、Mac等关键类的使用方法。通过AES对称加密、RSA非对称加密、HMAC消息认证码以及GCM模式AES加密等多个完整代码示例,展示不同加密场景的实现方案。同时提供密钥管理、异常处理、算法选择和性能优化等重要注意事项,为Java开发者提供实用的加密技术参考指南。

javax.crypto是Java密码学扩展(JCE)的核心包,提供了加密、密钥生成、密钥协商和消息认证码(MAC)等功能的类和接口。

主要类和接口

1、Cipher - 用于加密和解密操作

2、KeyGenerator - 生成对称密钥

3、KeyPairGenerator - 生成非对称密钥对

4、SecretKey - 对称密钥接口

5、Mac - 消息认证码

6、KeyAgreement - 密钥协商协议

示例代码

1. AES对称加密示例

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

public class AESExample {
    
    public static void main(String[] args) throws Exception {
        String originalText = "Hello, World!";
        
        // 生成AES密钥
        SecretKey secretKey = generateAESKey();
        
        // 加密
        String encryptedText = encrypt(originalText, secretKey);
        System.out.println("加密后: " + encryptedText);
        
        // 解密
        String decryptedText = decrypt(encryptedText, secretKey);
        System.out.println("解密后: " + decryptedText);
    }
    
    // 生成AES密钥
    public static SecretKey generateAESKey() throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128); // 可以是128, 192, 256位
        return keyGen.generateKey();
    }
    
    // 加密方法
    public static String encrypt(String plainText, SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }
    
    // 解密方法
    public static String decrypt(String encryptedText, SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
        return new String(decryptedBytes);
    }
}

2. RSA非对称加密示例

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

public class RSAExample {
    
    public static void main(String[] args) throws Exception {
        String originalText = "Hello, RSA Encryption!";
        
        // 生成RSA密钥对
        KeyPair keyPair = generateRSAKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        
        // 使用公钥加密
        String encryptedText = encrypt(originalText, publicKey);
        System.out.println("加密后: " + encryptedText);
        
        // 使用私钥解密
        String decryptedText = decrypt(encryptedText, privateKey);
        System.out.println("解密后: " + decryptedText);
    }
    
    // 生成RSA密钥对
    public static KeyPair generateRSAKeyPair() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        keyPairGen.initialize(2048); // 密钥长度
        return keyPairGen.generateKeyPair();
    }
    
    // 使用公钥加密
    public static String encrypt(String plainText, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }
    
    // 使用私钥解密
    public static String decrypt(String encryptedText, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
        return new String(decryptedBytes);
    }
}

3. HMAC消息认证码示例

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class HMACExample {
    
    public static void main(String[] args) throws Exception {
        String message = "重要消息需要验证完整性";
        String secret = "mySecretKey";
        
        // 生成HMAC
        String hmac = generateHMAC(message, secret);
        System.out.println("HMAC: " + hmac);
        
        // 验证HMAC
        boolean isValid = verifyHMAC(message, secret, hmac);
        System.out.println("HMAC验证结果: " + isValid);
    }
    
    // 生成HMAC
    public static String generateHMAC(String message, String secret) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
        mac.init(secretKeySpec);
        byte[] hmacBytes = mac.doFinal(message.getBytes());
        return Base64.getEncoder().encodeToString(hmacBytes);
    }
    
    // 验证HMAC
    public static boolean verifyHMAC(String message, String secret, String receivedHmac) throws Exception {
        String calculatedHmac = generateHMAC(message, secret);
        return calculatedHmac.equals(receivedHmac);
    }
}

4. 使用特定算法参数的AES加密

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import java.security.SecureRandom;
import java.util.Base64;

public class AESWithGCMExample {
    
    public static void main(String[] args) throws Exception {
        String originalText = "使用GCM模式的AES加密";
        
        // 生成密钥和初始化向量
        SecretKey secretKey = generateAESKey();
        byte[] iv = generateIV();
        
        // 加密
        String[] result = encryptWithGCM(originalText, secretKey, iv);
        System.out.println("加密后: " + result[0]);
        System.out.println("认证标签: " + result[1]);
        
        // 解密
        String decryptedText = decryptWithGCM(result[0], secretKey, iv, result[1]);
        System.out.println("解密后: " + decryptedText);
    }
    
    public static SecretKey generateAESKey() throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(256);
        return keyGen.generateKey();
    }
    
    public static byte[] generateIV() {
        byte[] iv = new byte[12]; // GCM推荐使用12字节的IV
        new SecureRandom().nextBytes(iv);
        return iv;
    }
    
    public static String[] encryptWithGCM(String plainText, SecretKey secretKey, byte[] iv) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        GCMParameterSpec spec = new GCMParameterSpec(128, iv); // 128位认证标签
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, spec);
        
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
        String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
        String authTag = Base64.getEncoder().encodeToString(cipher.getIV());
        
        return new String[]{encryptedText, authTag};
    }
    
    public static String decryptWithGCM(String encryptedText, SecretKey secretKey, byte[] iv, String authTag) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        GCMParameterSpec spec = new GCMParameterSpec(128, iv);
        cipher.init(Cipher.DECRYPT_MODE, secretKey, spec);
        
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
        return new String(decryptedBytes);
    }
}

重要注意事项

1、密钥管理:在实际应用中,密钥应该安全存储,不要硬编码在代码中

2、异常处理:密码学操作可能抛出多种异常,需要适当处理

3、算法选择:根据安全需求选择合适的算法和密钥长度

4、性能考虑:非对称加密比对称加密慢,通常用于加密小量数据或加密对称密钥

最后更新于4月前
本文由人工编写,AI优化,转载请注明原文地址: javax.crypto使用指南:Java加密解密完整代码示例

评论 (5)

发表评论

昵称:加载中...
米娅Mia米娅Mia2025-12-09 16:49:05
示例代码很实用,特别是AES加解密部分。请问如果密钥需要持久化存储,推荐用什么方式保存SecretKey对象呢?
林安妮林安妮2025-11-25 12:06:14
感谢分享这么详细的AES加密示例!代码很清晰,帮我快速理解了Cipher的使用。如果能补充一下密钥存储的最佳实践就更好了。
星空下的约定星空下的约定2025-11-19 13:22:56
非常实用的AES加密示例代码!正好解决了我在项目中遇到的数据加密需求,感谢作者的分享和整理。
小草莓小草莓2025-11-11 17:02:29
感谢分享这么详细的javax.crypto使用指南!代码示例很实用,让我快速理解了AES加密的实现。有个小疑问:如果使用256位密钥是否需要额外配置JCE策略文件?
管理员管理员2025-11-25 20:01:20
是的,需要额外配置JCE策略文件。一是因为历史出口限制,由于历史上美国的出口管制法规,Oracle JDK默认捆绑的“受限”策略文件将AES等对称加密算法的密钥长度限制在128位以内。二是策略文件限制,默认安装的策略文件不允许使用256位密钥的AES加密,会抛出类似 java.security.InvalidKeyException: Illegal key size 的异常。