Java加密保护案例

wen java案例 1

本文目录导读:

Java加密保护案例

  1. 完整的加密工具类示例
  2. 应用示例 - 用户认证系统
  3. 文件加密示例
  4. 安全最佳实践和注意事项
  5. 使用示例
  6. 关键安全建议

我将为您提供一个全面的Java加密保护案例,涵盖多种常见的加密技术和最佳实践。

完整的加密工具类示例

import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import java.security.spec.*;
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class EncryptionUtils {
    // 对称加密(AES)
    public static class AESUtil {
        private static final String AES_ALGORITHM = "AES";
        private static final String AES_TRANSFORMATION = "AES/GCM/NoPadding";
        private static final int IV_SIZE = 12; // GCM推荐12字节
        private static final int TAG_SIZE = 128; // GCM标签大小(位)
        /**
         * AES加密(GCM模式)
         */
        public static String encrypt(String plainText, String key) throws Exception {
            byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
            MessageDigest sha = MessageDigest.getInstance("SHA-256");
            keyBytes = sha.digest(keyBytes);
            SecretKeySpec secretKey = new SecretKeySpec(keyBytes, AES_ALGORITHM);
            // 生成随机IV
            byte[] iv = new byte[IV_SIZE];
            SecureRandom secureRandom = new SecureRandom();
            secureRandom.nextBytes(iv);
            Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(TAG_SIZE, iv));
            byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
            // 组合IV和密文
            byte[] result = new byte[IV_SIZE + encryptedBytes.length];
            System.arraycopy(iv, 0, result, 0, IV_SIZE);
            System.arraycopy(encryptedBytes, 0, result, IV_SIZE, encryptedBytes.length);
            return Base64.getEncoder().encodeToString(result);
        }
        /**
         * AES解密(GCM模式)
         */
        public static String decrypt(String encryptedText, String key) throws Exception {
            byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
            // 提取IV和密文
            byte[] iv = new byte[IV_SIZE];
            byte[] cipherBytes = new byte[encryptedBytes.length - IV_SIZE];
            System.arraycopy(encryptedBytes, 0, iv, 0, IV_SIZE);
            System.arraycopy(encryptedBytes, IV_SIZE, cipherBytes, 0, cipherBytes.length);
            byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
            MessageDigest sha = MessageDigest.getInstance("SHA-256");
            keyBytes = sha.digest(keyBytes);
            SecretKeySpec secretKey = new SecretKeySpec(keyBytes, AES_ALGORITHM);
            Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
            cipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(TAG_SIZE, iv));
            byte[] decryptedBytes = cipher.doFinal(cipherBytes);
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        }
    }
    // 非对称加密(RSA)
    public static class RSAUtil {
        private PrivateKey privateKey;
        private PublicKey publicKey;
        /**
         * 生成密钥对
         */
        public void generateKeyPair() throws Exception {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            this.privateKey = keyPair.getPrivate();
            this.publicKey = keyPair.getPublic();
        }
        /**
         * RSA加密(使用公钥)
         */
        public String encrypt(String plainText) throws Exception {
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(encryptedBytes);
        }
        /**
         * RSA解密(使用私钥)
         */
        public String decrypt(String encryptedText) throws Exception {
            byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        }
        /**
         * 获取公钥字符串
         */
        public String getPublicKeyString() {
            return Base64.getEncoder().encodeToString(publicKey.getEncoded());
        }
        /**
         * 获取私钥字符串(应安全存储)
         */
        public String getPrivateKeyString() {
            return Base64.getEncoder().encodeToString(privateKey.getEncoded());
        }
        /**
         * 从字符串加载公钥
         */
        public void loadPublicKey(String publicKeyString) throws Exception {
            byte[] keyBytes = Base64.getDecoder().decode(publicKeyString);
            X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            this.publicKey = keyFactory.generatePublic(spec);
        }
        /**
         * 从字符串加载私钥
         */
        public void loadPrivateKey(String privateKeyString) throws Exception {
            byte[] keyBytes = Base64.getDecoder().decode(privateKeyString);
            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            this.privateKey = keyFactory.generatePrivate(spec);
        }
    }
    // 哈希函数
    public static class HashUtil {
        /**
         * SHA-256哈希
         */
        public static String sha256(String input) throws Exception {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash);
        }
        /**
         * SHA-512哈希(更安全)
         */
        public static String sha512(String input) throws Exception {
            MessageDigest digest = MessageDigest.getInstance("SHA-512");
            byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash);
        }
        /**
         * PBKDF2密码哈希(用于密码存储)
         */
        public static String pbkdf2Hash(String password, String salt, int iterations, int keyLength) 
                throws Exception {
            PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), 
                                            salt.getBytes(StandardCharsets.UTF_8), 
                                            iterations, keyLength);
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
            byte[] hash = factory.generateSecret(spec).getEncoded();
            return bytesToHex(hash);
        }
        private static String bytesToHex(byte[] bytes) {
            StringBuilder result = new StringBuilder();
            for (byte b : bytes) {
                result.append(String.format("%02x", b));
            }
            return result.toString();
        }
    }
    // 数字签名
    public static class DigitalSignatureUtil {
        private PrivateKey privateKey;
        private PublicKey publicKey;
        /**
         * 生成签名
         */
        public String sign(String data) throws Exception {
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(privateKey);
            signature.update(data.getBytes(StandardCharsets.UTF_8));
            byte[] signatureBytes = signature.sign();
            return Base64.getEncoder().encodeToString(signatureBytes);
        }
        /**
         * 验证签名
         */
        public boolean verify(String data, String signatureString) throws Exception {
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initVerify(publicKey);
            signature.update(data.getBytes(StandardCharsets.UTF_8));
            byte[] signatureBytes = Base64.getDecoder().decode(signatureString);
            return signature.verify(signatureBytes);
        }
    }
}

应用示例 - 用户认证系统

import java.util.Date;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class UserAuthenticationService {
    private static final ConcurrentHashMap<String, UserAccount> users = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<String, TokenInfo> activeTokens = new ConcurrentHashMap<>();
    // 用户账户类
    public static class UserAccount {
        private String username;
        private String passwordHash;
        private String salt;
        private String email;
        private Date createdAt;
        public UserAccount(String username, String passwordHash, String salt, String email) {
            this.username = username;
            this.passwordHash = passwordHash;
            this.salt = salt;
            this.email = email;
            this.createdAt = new Date();
        }
        // Getters and setters...
    }
    // 令牌信息类
    public static class TokenInfo {
        private String token;
        private String username;
        private Date expiryDate;
        public TokenInfo(String token, String username, Date expiryDate) {
            this.token = token;
            this.username = username;
            this.expiryDate = expiryDate;
        }
        public boolean isExpired() {
            return expiryDate.before(new Date());
        }
        // Getters and setters...
    }
    /**
     * 用户注册
     */
    public boolean register(String username, String password, String email) {
        if (users.containsKey(username)) {
            return false;
        }
        try {
            // 生成随机盐值
            String salt = generateSalt();
            // 使用PBKDF2进行密码哈希
            String passwordHash = EncryptionUtils.HashUtil.pbkdf2Hash(password, salt, 10000, 256);
            // 创建用户账户
            UserAccount account = new UserAccount(username, passwordHash, salt, email);
            users.put(username, account);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 用户登录
     */
    public String login(String username, String password) {
        UserAccount account = users.get(username);
        if (account == null) {
            return null;
        }
        try {
            // 验证密码
            String hash = EncryptionUtils.HashUtil.pbkdf2Hash(password, account.salt, 10000, 256);
            if (!hash.equals(account.passwordHash)) {
                return null;
            }
            // 生成访问令牌
            String token = generateToken();
            Date expiryDate = new Date(System.currentTimeMillis() + 30 * 60 * 1000); // 30分钟
            TokenInfo tokenInfo = new TokenInfo(token, username, expiryDate);
            activeTokens.put(token, tokenInfo);
            return token;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 验证令牌
     */
    public boolean verifyToken(String token) {
        TokenInfo tokenInfo = activeTokens.get(token);
        if (tokenInfo == null || tokenInfo.isExpired()) {
            activeTokens.remove(token); // 清理过期令牌
            return false;
        }
        return true;
    }
    /**
     * 密码重置(演示加密数据的应用)
     */
    public boolean resetPassword(String username, String oldPassword, String newPassword) {
        UserAccount account = users.get(username);
        if (account == null) {
            return false;
        }
        try {
            // 验证旧密码
            String oldHash = EncryptionUtils.HashUtil.pbkdf2Hash(oldPassword, account.salt, 10000, 256);
            if (!oldHash.equals(account.passwordHash)) {
                return false;
            }
            // 更新密码
            String newSalt = generateSalt();
            String newHash = EncryptionUtils.HashUtil.pbkdf2Hash(newPassword, newSalt, 10000, 256);
            // 更新用户账户(实际应用中需要更新数据库)
            // account.setPasswordHash(newHash);
            // account.setSalt(newSalt);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    // 辅助方法
    private String generateSalt() {
        byte[] salt = new byte[16];
        new SecureRandom().nextBytes(salt);
        return Base64.getEncoder().encodeToString(salt);
    }
    private String generateToken() {
        return UUID.randomUUID().toString() + System.currentTimeMillis();
    }
}

文件加密示例

import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.SecureRandom;
public class FileEncryptionUtil {
    /**
     * 加密文件
     */
    public static void encryptFile(String sourceFilePath, String destFilePath, String key) 
            throws Exception {
        // 生成随机IV
        byte[] ivBytes = new byte[16];
        SecureRandom secureRandom = new SecureRandom();
        secureRandom.nextBytes(ivBytes);
        // 初始化密钥
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(ivBytes));
        try (FileInputStream inputStream = new FileInputStream(sourceFilePath);
             FileOutputStream outputStream = new FileOutputStream(destFilePath)) {
            // 写入IV到文件头部
            outputStream.write(ivBytes);
            // 加密内容
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                byte[] output = cipher.update(buffer, 0, bytesRead);
                if (output != null) {
                    outputStream.write(output);
                }
            }
            byte[] outputBytes = cipher.doFinal();
            if (outputBytes != null) {
                outputStream.write(outputBytes);
            }
        }
    }
    /**
     * 解密文件
     */
    public static void decryptFile(String sourceFilePath, String destFilePath, String key) 
            throws Exception {
        try (FileInputStream inputStream = new FileInputStream(sourceFilePath);
             FileOutputStream outputStream = new FileOutputStream(destFilePath)) {
            // 读取IV
            byte[] ivBytes = new byte[16];
            int ivRead = inputStream.read(ivBytes);
            if (ivRead != 16) {
                throw new IllegalArgumentException("加密文件格式错误");
            }
            // 初始化密钥
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(ivBytes));
            // 解密内容
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                byte[] output = cipher.update(buffer, 0, bytesRead);
                if (output != null) {
                    outputStream.write(output);
                }
            }
            byte[] outputBytes = cipher.doFinal();
            if (outputBytes != null) {
                outputStream.write(outputBytes);
            }
        }
    }
    /**
     * 安全的文件删除(覆盖后再删除)
     */
    public static void secureDeleteFile(String filePath) throws IOException {
        Path path = Paths.get(filePath);
        if (!Files.exists(path)) {
            return;
        }
        // 获取文件大小
        long size = Files.size(path);
        // 多次覆盖文件内容
        try (RandomAccessFile raf = new RandomAccessFile(filePath, "rw")) {
            raf.seek(0);
            raf.write(new byte[(int) size]);
            raf.getFD().sync();
        }
        // 删除文件
        Files.deleteIfExists(path);
    }
}

安全最佳实践和注意事项

public class SecurityBestPractices {
    /**
     * 1. 使用安全的随机数生成器
     */
    public static byte[] generateSecureRandomBytes(int length) {
        SecureRandom secureRandom = new SecureRandom();
        byte[] bytes = new byte[length];
        secureRandom.nextBytes(bytes);
        return bytes;
    }
    /**
     * 2. 正确的密码存储方式
     */
    public static String hashPasswordCorrectly(String password) {
        try {
            // 使用BCrypt(通过第三方库)或Argon2(推荐)
            // 这里使用PBKDF2作为示例
            String salt = generateSalt();
            int iterations = 10000; // 应该足够大
            int keyLength = 256;
            return EncryptionUtils.HashUtil.pbkdf2Hash(password, salt, iterations, keyLength);
        } catch (Exception e) {
            throw new RuntimeException("密码哈希失败", e);
        }
    }
    /**
     * 3. 使用密钥管理系统(示例接口)
     */
    public interface KeyManagementService {
        String generateKey();
        String generateIV();
        String encryptKeyWithMasterKey(String key);
        String decryptKeyWithMasterKey(String encryptedKey);
        void rotateKey(String keyId);
    }
    /**
     * 4. 内容加密vs哈希的区别
     */
    public static class HashingVsEncryption {
        // 哈希:不可逆,用于密码验证
        public static String hashForVerification(String data) throws Exception {
            return EncryptionUtils.HashUtil.sha256(data);
        }
        // 加密:可逆,用于数据传输和存储
        public static String encryptForStorage(String data, String key) throws Exception {
            return EncryptionUtils.AESUtil.encrypt(data, key);
        }
    }
    /**
     * 5. 安全的字符串比较(防止时序攻击)
     */
    public static boolean secureCompare(String str1, String str2) {
        if (str1 == null || str2 == null) return false;
        byte[] bytes1 = str1.getBytes(StandardCharsets.UTF_8);
        byte[] bytes2 = str2.getBytes(StandardCharsets.UTF_8);
        if (bytes1.length != bytes2.length) return false;
        int result = 0;
        for (int i = 0; i < bytes1.length; i++) {
            result |= bytes1[i] ^ bytes2[i];
        }
        return result == 0;
    }
    private static String generateSalt() {
        byte[] salt = new byte[16];
        new SecureRandom().nextBytes(salt);
        return Base64.getEncoder().encodeToString(salt);
    }
}

使用示例

public class EncryptionExample {
    public static void main(String[] args) {
        try {
            // 1. AES加密示例
            String plainText = "Hello, 这是一个加密示例!";
            String aesKey = "MySecretKey123";
            String encrypted = EncryptionUtils.AESUtil.encrypt(plainText, aesKey);
            String decrypted = EncryptionUtils.AESUtil.decrypt(encrypted, aesKey);
            System.out.println("AES加密结果: " + encrypted);
            System.out.println("AES解密结果: " + decrypted);
            // 2. RSA加密示例
            EncryptionUtils.RSAUtil rsaUtil = new EncryptionUtils.RSAUtil();
            rsaUtil.generateKeyPair();
            String rsaEncrypted = rsaUtil.encrypt(plainText);
            String rsaDecrypted = rsaUtil.decrypt(rsaEncrypted);
            System.out.println("RSA加密结果: " + rsaEncrypted);
            System.out.println("RSA解密结果: " + rsaDecrypted);
            // 3. 哈希示例
            String hash = EncryptionUtils.HashUtil.sha256(plainText);
            System.out.println("SHA-256哈希: " + hash);
            // 4. 密码存储示例
            UserAuthenticationService authService = new UserAuthenticationService();
            authService.register("user1", "Password123!", "user1@example.com");
            String token = authService.login("user1", "Password123!");
            System.out.println("用户认证令牌: " + token);
            System.out.println("令牌验证结果: " + authService.verifyToken(token));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

关键安全建议

  1. 密钥管理

    • 永远不要硬编码密钥在代码中
    • 使用专业的密钥管理服务(如AWS KMS、HashiCorp Vault)
  2. 算法选择

    • 数据加密:AES-256-GCM
    • 密钥交换:RSA-2048 或 ECC
    • 密码存储:Argon2、BCrypt、scrypt(PBKDF2作为备选)
  3. 安全实践

    • 使用随机IV
    • 实施密钥轮换策略
    • 记录安全事件日志
    • 定期进行安全审计
  4. 传输安全

    • 始终使用HTTPS/TLS
    • 实施证书固定
    • 使用HSTS

这个案例涵盖了Java加密的主要方面,实际项目中应根据具体需求选择合适的加密方案。

上一篇Java反编译案例

下一篇当前分类已是最新一篇

抱歉,评论功能暂时关闭!