You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle加密字段存入SQL Server后,C#解密失败的技术求助

解决Oracle AES加密字段在C#中解密失败的问题

我来帮你拆解一下问题所在,你的C#解密代码有几个关键错误,我们一步步修正就能解决:

问题分析

先回顾你的Oracle加密逻辑的几个细节,这些是导致解密失败的核心原因:

  1. IV的处理:你用的是AES-CBC模式,Oracle的dbms_crypto.encrypt在未指定IV参数时,会自动生成一个16字节的随机IV,并且把这个IV直接附加在密文的最前面返回。你的C#代码完全没处理IV,直接解密整个数据,肯定会出错。
  2. 密钥字符串错误:你的Oracle代码里的g_static中的>是HTML转义字符,实际对应的是普通的>符号,但你的C#代码里直接写了>,导致密钥和Oracle端不一致,这也是解密失败的重要原因。
  3. 密文字符串转换错误:你把十六进制格式的密文直接用Encoding.UTF8.GetBytes转成字节数组,这相当于把每个十六进制字符(比如D、8)转成UTF8字节,而不是把十六进制字符串解析成原始的加密字节,这完全搞错了密文的格式。
  4. 填充模式的误解:Oracle用的是PKCS5填充,而C#里的PaddingMode.PKCS7和它在AES场景下是等价的(因为AES的块大小是16字节,PKCS5针对8字节块,PKCS7支持任意块大小,16字节时两者效果一致),所以填充模式本身不是问题,是前面的错误导致填充校验失败。

修正后的C#解密代码

下面是修复所有问题后的代码,我加了详细注释:

using System;
using System.Security.Cryptography;
using System.Text;

class DecryptOracleAes
{
    static void Main()
    {
        // 你的十六进制密文字符串
        string hexEncryptedData = "D869C2E0895B822465925C1C41F11339";
        // 修正后的密钥:把>替换成实际的>符号,和Oracle端的g_static一致
        string keyString = "!20R8QO__RKEEJ+*>;I:V?U=:F 4?T9L";

        // 1. 把十六进制字符串转换成原始字节数组(替换你的Encoding.UTF8.GetBytes错误用法)
        byte[] encryptedWithIv = Convert.FromHexString(hexEncryptedData);

        // 2. 分离IV和实际密文:AES块大小是16字节,前16字节是Oracle自动生成的IV
        byte[] iv = new byte[16];
        byte[] ciphertext = new byte[encryptedWithIv.Length - 16];
        Array.Copy(encryptedWithIv, 0, iv, 0, 16);
        Array.Copy(encryptedWithIv, 16, ciphertext, 0, ciphertext.Length);

        // 3. 初始化AES配置
        using (Aes aes = Aes.Create())
        {
            aes.Key = Encoding.UTF8.GetBytes(keyString);
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7; // 和Oracle的PKCS5填充等价
            aes.IV = iv; // 设置从密文中分离出的IV

            // 4. 执行解密
            using (ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
            {
                byte[] decryptedBytes = decryptor.TransformFinalBlock(ciphertext, 0, ciphertext.Length);
                string decryptedText = Encoding.UTF8.GetString(decryptedBytes);
                Console.WriteLine("解密结果:" + decryptedText);
            }
        }
    }

    // 如果你用的是.NET 5以下版本,Convert.FromHexString不可用,用这个方法替代
    static byte[] HexToByteArray(string hex)
    {
        int byteCount = hex.Length / 2;
        byte[] result = new byte[byteCount];
        for (int i = 0; i < byteCount; i++)
        {
            result[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
        }
        return result;
    }
}

额外验证点

  • 检查密钥长度:AES-256需要32字节的密钥,你可以打印Encoding.UTF8.GetBytes(keyString).Length,如果结果不是32,说明你的密钥字符串还是和Oracle端不一致,需要重新核对g_static的原始值。
  • 确认密文包含IV前缀:如果你的Oracle加密逻辑是手动指定了IV(而不是自动生成),那你需要获取对应的IV值替换代码中的分离逻辑,否则还是会解密失败。

内容的提问来源于stack exchange,提问作者prvn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 18:37:27