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

将VB6调用advapi32.dll的RC4解密逻辑迁移至.NET的求助

问题描述

需要从遗留系统向第三方新系统迁移数据,部分加密数据需解密后供采用现代加密方案的新系统使用。遗留解密代码由VB6编写,调用advapi32.dll的Crypt系列API,采用PROV_RSA_FULL、SHA1及RC4算法。转换为C#代码时出现System.Security.Cryptography.CryptographicException: 待解密数据长度无效错误,无法正常运行。当前环境为Windows Server 2016,需在.NET中正确实现对应RC4解密逻辑,其他加密兼容性问题后续处理。

遗留VB6解密代码

'Const ENCRYPT_BLOCK_SIZE as Integer = 8

Dim hCSP As Long
Dim strContexte As String
Dim Password as String
Dim lngPassword  as Long
Dim strEncrypted as String
Dim lngEncrypted as Long
Dim strBuffer as String
Dim lngBuffer as Long
Dim hHash as Long
Dim lngRC as Long

strContexte = "Some Context"
Password = "SomeString"
lngPassword = Len(Password)

strEncrypted = "String to decrypt"
lngEncrypted = Len(strEncrypted)
lngBuffer = lngEncrypted + ENCRYPT_BLOCK_SIZE 
LSet strBuffer = strEncrypted 

lngRC = CryptAcquireContext(hCSP, strContext, "Microsoft Base Cryptographic Provider v1.0", PROV_RSA_FULL, CRYPT_MACHINE_KEYSET)
  If Not CBool(lngRC) Then
    If Err.LastDllError = NTE_BAD_KEYSET Then
      lngRC = CryptAcquireContext(hCSP, strContext, "Microsoft Base Cryptographic Provider v1.0", PROV_RSA_FULL, CRYPT_NEWKEYSET + CRYPT_MACHINE_KEYSET)
  End If

  lngRC = CryptCreateHash(hCSP, CALG_SHA1, 0, 0, hHash)
  lngRC = CryptHashData(hHash, Password, lngPassword, 0)
  lngRC = CryptDeriveKey(hCSP, CALG_RC4, hHash, 0, hHash)
  lngRC = CryptDecrypt(hHash, 0, 1, 0, strBuffer, lngBuffer)

当前错误的C#实现代码

string Password = "SomeString";
string info = "String to decrypt";
byte[] value = Convert.ToByte(info, 16); // 语法错误,且未匹配VB6字符串编码

long lngInfo = info.Length;
long lngBuffer = lngInfo + 8;
byte[] Buffer = new byte[lngBuffer];

value.CopyTo(Buffer, 0); 

byte[] key;
using (PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, null))
{
    key = pdb.CryptDeriveKey("TripleDES", "SHA1", 0, new byte[8]);
}

byte[] decrypted;
using (var prov = new TripleDESCryptoServiceProvider())
{   
    using (var decryptor = prov.CreateDecryptor(key, new byte[8]))
    {
        decrypted = decryptor.TransformFinalBlock(Buffer, 0, lngBuffer);
    }
}

问题分析与正确实现

核心错误点

  1. 原VB6使用RC4算法,但C#代码误用了TripleDES,完全偏离目标算法。
  2. 未匹配VB6字符串的UTF-16LE编码逻辑,加密数据的字节转换方式错误。
  3. CryptDeriveKey的调用参数不匹配,RC4不需要IV,且密钥派生逻辑需对应SHA1+RC4的组合。

正确的C#实现

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

public class Vb6Rc4Decryptor
{
    public static string Decrypt(string encryptedData, string password, string context = "Some Context")
    {
        // 1. 将VB6加密字符串转换为字节数组(VB6默认UTF-16LE编码)
        byte[] encryptedBytes = Encoding.Unicode.GetBytes(encryptedData);

        // 2. 匹配CryptDeriveKey的密钥派生逻辑:用上下文作为盐,SHA1哈希派生RC4密钥
        byte[] key;
        using (var pdb = new PasswordDeriveBytes(password, Encoding.Unicode.GetBytes(context)))
        {
            // RC4默认128位密钥,对应CryptDeriveKey的默认参数
            key = pdb.CryptDeriveKey("RC4", "SHA1", 128, new byte[0]);
        }

        // 3. RC4解密(RC4无需IV)
        byte[] decryptedBytes;
        using (var rc4 = new RC4CryptoServiceProvider())
        {
            using (var decryptor = rc4.CreateDecryptor(key, null))
            {
                decryptedBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
            }
        }

        // 4. 转换回字符串并移除VB6 LSet填充的空字符
        return Encoding.Unicode.GetString(decryptedBytes).TrimEnd('\0');
    }

    // 测试示例
    public static void Main()
    {
        string testPassword = "SomeString";
        string testEncrypted = "String to decrypt"; // 替换为实际加密数据
        string result = Decrypt(testEncrypted, testPassword);
        Console.WriteLine("解密结果: " + result);
    }
}

关键细节说明

  • VB6的CryptAcquireContext指定的strContext需作为盐值传入PasswordDeriveBytes,确保密钥派生逻辑与原代码完全一致。
  • RC4算法不需要初始化向量(IV),因此CreateDecryptor时IV参数传null。
  • VB6字符串默认采用UTF-16LE编码,所有字符串与字节数组的转换必须使用Encoding.Unicode。
  • 解密后需调用TrimEnd('\0')移除VB6中LSet语句填充的空字符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 18:40:24