Bảo mật chuỗi ký tự trong Java bằng cách kết hợp Base64 và mã hóa Triple DES

Trong quá trình phát triển ứng dụng, việc truyền tải dữ liệu dưới dạng văn bản thuần túy (plain text) thường tiềm ẩn nhiều rủi ro bảo mật hoặc có thể bị các hệ thống tường lửa, gateway chặn lại. Để giải quyết vấn đề này, một kỹ thuật phổ biến là mã hóa dữ liệu trước khi gửi đi. Phương pháp dưới đây kết hợp giữa việc mã hóa Base64 và thuật toán Triple DES (3DES) để tăng cường lớp bảo vệ cho thông tin.

1. Lớp xử lý mã hóa Triple DES

Thuật toán 3DES yêu cầu một khóa có độ dài 24 byte (192 bit). Dữ liệu sau khi mã hóa sẽ được chuyển đổi sang định dạng Hex (thập lục phân) để dễ dàng lưu trữ và truyền tải.

import org.apache.commons.codec.binary.Hex;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

public class TripleDesProvider {

    private static final String ALGORITHM = "DESede/ECB/PKCS5Padding";

    /**
     * Thực hiện mã hóa 3DES
     * @param source Dữ liệu cần mã hóa
     * @param secretKey Khóa bí mật (phải đủ 24 ký tự)
     * @return Chuỗi Hex sau khi mã hóa
     */
    public static String encrypt(String source, String secretKey) {
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "DESede");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);
            
            byte[] cipherBytes = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));
            return Hex.encodeHexString(cipherBytes).toUpperCase();
        } catch (Exception e) {
            throw new RuntimeException("Lỗi trong quá trình mã hóa 3DES", e);
        }
    }

    /**
     * Thực hiện giải mã 3DES
     * @param hexData Chuỗi Hex cần giải mã
     * @param secretKey Khóa bí mật
     * @return Dữ liệu gốc sau khi giải mã
     */
    public static String decrypt(String hexData, String secretKey) {
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "DESede");
            cipher.init(Cipher.DECRYPT_MODE, keySpec);
            
            byte[] decodedHex = Hex.decodeHex(hexData.toCharArray());
            byte[] originalBytes = cipher.doFinal(decodedHex);
            return new String(originalBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("Lỗi trong quá trình giải mã 3DES", e);
        }
    }
}

2. Kết hợp Base64 và mã hóa dữ liệu

Ở bước này, chúng ta sẽ sử dụng thư viện tiêu chuẩn java.util.Base64 (có sẵn từ Java 8 trở lên) để mã hóa chuỗi ký tự sang Base64 trước khi áp dụng thuật toán 3DES. Quy trình này giúp đảm bảo dữ liệu đầu vào cho khối mã hóa luôn ở định dạng chuẩn.

import java.util.Base64;
import java.util.Objects;

public class SecurityService {

    private static final String APP_KEY = "abc123def456ghi789jkl012"; // Khóa 24 byte

    /**
     * Chuyển đổi sang Base64 và mã hóa 3DES
     * @param plainText Văn bản thô
     * @return Chuỗi đã được bảo mật
     */
    public static String encodeAndEncrypt(String plainText) {
        if (plainText == null || plainText.isEmpty()) {
            return "";
        }

        // Bước 1: Encode sang Base64
        String base64Encoded = Base64.getEncoder().encodeToString(plainText.getBytes(StandardCharsets.UTF_8));

        // Bước 2: Mã hóa 3DES
        return TripleDesProvider.encrypt(base64Encoded, APP_KEY);
    }

    /**
     * Giải mã 3DES và đưa về định dạng gốc từ Base64
     * @param securedText Chuỗi đã mã hóa
     * @return Văn bản gốc
     */
    public static String decryptAndDecode(String securedText) {
        if (securedText == null || securedText.isEmpty()) {
            return "";
        }

        // Bước 1: Giải mã 3DES
        String base64Result = TripleDesProvider.decrypt(securedText, APP_KEY);

        // Bước 2: Decode Base64
        byte[] originalBytes = Base64.getDecoder().decode(base64Result);
        return new String(originalBytes, StandardCharsets.UTF_8);
    }
}

Việc sử dụng StandardCharsets.UTF_8 giúp tránh các lỗi liên quan đến font chữ hoặc ký tự đặc biệt khi ứng dụng chạy trên các môi trường hệ điều hành khác nhau. Đồng thời, cấu trúc mã nguồn được tách biệt giữa logic mã hóa lõi và logic xử lý nghiệp vụ giúp hệ thống dễ dàng bảo trì và mở rộng hơn.

Thẻ: Java cryptography 3des base64 Security

Đăng vào ngày 23 tháng 7 lúc 19:28