Skip to content

加密与解密

加密算法

  • 加密算法为AES,加密模式为GCM,填充方式为NoPadding,密钥长度为256位(bit),IV向量为AES密钥的前128位(bit)

加密说明

  • 明文数据进行AES加密后,对结果做Base64编码,得到密文数据,编码格式为UTF-8。 注:仅针对敏感数据进行AES加密,需加密的字段见具体接口参数备注。

解密说明

  • 密文数据先进行Base64解码,然后再进行AES解密,编码格式为UTF-8。

代码示例

  • 加密方法

Java 实现

java
/**
     * 加密方法
     * @param data 待加密的数据
     * @param key  密钥
     * @return 加密后的数据(Base64编码)
     */
    public static String encrypt(String data, String key) {
        try {
            SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
            GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, key.substring(0, 16).getBytes()); // 初始化向量IV
            cipher.init(Cipher.ENCRYPT_MODE, skey, gcmParameterSpec);
            byte[] encryptedData = cipher.doFinal(data.getBytes());
            byte[] iv = cipher.getIV();
            return Base64.getEncoder().encodeToString(iv) + ":" + Base64.getEncoder().encodeToString(encryptedData);
        } catch (Exception e) {
            logger.error("AES encrypt error:", e);
            return null;
        }
    }

.NET 实现

.NET
/**
     * 加密方法
     * @param data 待加密的数据
     * @param key  密钥
     * @return 加密后的数据(Base64编码)
     */
    public static string Encrypt(string data, string key)
        {
            try
            {
                byte[] keyBytes = Encoding.UTF8.GetBytes(key);
                if (keyBytes.Length != 32)
                    throw new ArgumentException("密钥长度必须为32字节(256位)");

                // Java示例中使用16字节IV
                byte[] ivBytes = new byte[16];
                Array.Copy(keyBytes, 0, ivBytes, 0, 16);

                byte[] plainBytes = Encoding.UTF8.GetBytes(data);

                // 使用BouncyCastle库(需要安装)
                return EncryptWithBouncyCastle(plainBytes, keyBytes, ivBytes);
            }
            catch (Exception e)
            {
                Console.Error.WriteLine($"AES encrypt error: {e}");
                return null;
            }
        }

	private static string EncryptWithBouncyCastle(byte[] plainBytes, byte[] keyBytes, byte[] ivBytes)
        {
            // 使用BouncyCastle处理16字节IV
            // Install-Package Portable.BouncyCastle
            AesEngine cipher = new AesEngine();
            var gcmCipher = new GcmBlockCipher(cipher);
            var parameters = new AeadParameters(
                new KeyParameter(keyBytes),
                128, // MAC大小
                ivBytes
            );

            gcmCipher.Init(true, parameters);

            byte[] encryptedBytes = new byte[gcmCipher.GetOutputSize(plainBytes.Length)];
            int len = gcmCipher.ProcessBytes(plainBytes, 0, plainBytes.Length, encryptedBytes, 0);
            gcmCipher.DoFinal(encryptedBytes, len);

            string ivBase64 = Convert.ToBase64String(ivBytes);
            string encryptedBase64 = Convert.ToBase64String(encryptedBytes);

            return $"{ivBase64}:{encryptedBase64}";
        }
  • 解密方法

Java 实现

java
    /**
     * 解密方法
     * @param encryptedData 待解密的数据(Base64编码)
     * @param key  密钥
     * @return 解密后的数据
     */
    public static String decrypt(String encryptedData, String key) {
        try {
            SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
            String[] parts = encryptedData.split(":");
            byte[] iv = Base64.getDecoder().decode(parts[0]);
            byte[] encryptedDataBytes = Base64.getDecoder().decode(parts[1]);

            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
            GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, iv);
            cipher.init(Cipher.DECRYPT_MODE, skey, gcmParameterSpec);
            byte[] original = cipher.doFinal(encryptedDataBytes);
            return new String(original);
        } catch (Exception e) {
            logger.error("AES decrypt error:", e);
            return null;
        }
    }

.NET 实现

.NET
public static string Decrypt(string encryptedData, string key)
        {
            try
            {
                // 1. 验证输入参数
                if (string.IsNullOrEmpty(encryptedData))
                    throw new ArgumentNullException(nameof(encryptedData));
                if (string.IsNullOrEmpty(key))
                    throw new ArgumentNullException(nameof(key));

                // 2. 准备密钥
                byte[] keyBytes = Encoding.UTF8.GetBytes(key);
                if (keyBytes.Length != 32)
                    throw new ArgumentException("密钥必须为32字节(256位)");

                // 3. 分割IV和密文
                string[] parts = encryptedData.Split(':');
                if (parts.Length != 2)
                    throw new FormatException("加密数据格式不正确,应为 'IV:密文' 格式");

                byte[] iv = Convert.FromBase64String(parts[0]);
                byte[] cipherText = Convert.FromBase64String(parts[1]);

                // 4. 验证IV长度(GCM通常支持12或16字节)
                if (iv.Length != 12 && iv.Length != 16)
                    Console.WriteLine($"警告:非标准IV长度 {iv.Length} 字节");

                // 5. 使用BouncyCastle解密
                var cipher = new GcmBlockCipher(new AesEngine());
                var parameters = new AeadParameters(
                    new KeyParameter(keyBytes),
                    128, // 认证标签长度(位)
                    iv
                );

                cipher.Init(false, parameters);

                // 6. 执行解密
                byte[] plainBytes = new byte[cipher.GetOutputSize(cipherText.Length)];
                int len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainBytes, 0);
                cipher.DoFinal(plainBytes, len);

                // 7. 返回解密结果(移除可能的空字符)
                return Encoding.UTF8.GetString(plainBytes).TrimEnd('\0');
            }
            catch (Exception ex)
            {
                Console.WriteLine($"解密失败: {ex.Message}");
                return null;
            }
        }