wenminjie
2026-08-03 ddc84625dcdb22a1ec2407f6adc7eb2e7a839ef0
talent-card-server/src/main/java/com/talentcard/server/common/SensitiveDataCrypto.java
@@ -3,6 +3,7 @@
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
@@ -16,6 +17,7 @@
public class SensitiveDataCrypto {
    private static final SecureRandom RANDOM = new SecureRandom();
    private static final String VERSION_PREFIX = "v1:";
    private final byte[] key;
    public SensitiveDataCrypto(@Value("${app.privacy.encryption-key}") String encryptionKey) {
@@ -37,9 +39,27 @@
            byte[] payload = new byte[iv.length + encrypted.length];
            System.arraycopy(iv, 0, payload, 0, iv.length);
            System.arraycopy(encrypted, 0, payload, iv.length, encrypted.length);
            return "v1:" + Base64.getUrlEncoder().withoutPadding().encodeToString(payload);
            return VERSION_PREFIX + Base64.getUrlEncoder().withoutPadding().encodeToString(payload);
        } catch (Exception exception) {
            throw new BusinessException(ErrorCode.INTERNAL_ERROR, "敏感信息加密失败");
        }
    }
}
    public String decrypt(String cipherText) {
        if (cipherText == null || cipherText.isBlank()) return "";
        if (!cipherText.startsWith(VERSION_PREFIX)) return cipherText;
        try {
            byte[] payload = Base64.getUrlDecoder().decode(cipherText.substring(VERSION_PREFIX.length()));
            if (payload.length <= 12) {
                throw new IllegalArgumentException("Invalid encrypted payload");
            }
            byte[] iv = Arrays.copyOfRange(payload, 0, 12);
            byte[] encrypted = Arrays.copyOfRange(payload, 12, payload.length);
            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new GCMParameterSpec(128, iv));
            return new String(cipher.doFinal(encrypted), StandardCharsets.UTF_8);
        } catch (Exception exception) {
            throw new BusinessException(ErrorCode.INTERNAL_ERROR, "敏感信息解密失败");
        }
    }
}