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

C# RSACryptoServiceProvider与C++ CryptoAPI同步解密报错解决

修复C++ RSA加密与C#解密的"参数不正确"异常

问题根源分析

  • C++加密逻辑错误:代码未将待加密明文写入缓冲区,直接调用CryptEncrypt会加密随机数据,且dwRead初始值设置不符合API要求。
  • 密钥格式不匹配:需确保C++导入的公钥与C#导入的私钥属于同一密钥对,且密钥的CSP Blob格式完全兼容。
  • RSA块大小与填充一致性问题:2048位RSA采用PKCS#1 v1.5填充时,最大明文长度为245字节(256-11),加密后密文固定为256字节;C#中Decrypt第二个参数设为false对应PKCS#1 v1.5填充,需确保C++端使用相同填充模式。

具体修复步骤

1. 修正C++加密代码

将待加密明文写入缓冲区,正确设置参数,添加资源释放与错误检测:

// 示例待加密明文
std::vector<unsigned char> plaintext = {0x01, 0x02, 0x03};
DWORD plaintextLen = plaintext.size();

HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hCryptKey = NULL;
BOOL bReturn = FALSE;

do {
    // 获取加密上下文
    bReturn = CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
    if (!bReturn) break;

    // 导入配对的公钥(确保公钥为CSP Blob格式)
    bReturn = CryptImportKey(hCryptProv, vecPublicKey.data(), vecPublicKey.size(), NULL, 0, &hCryptKey);
    if (!bReturn) break;

    // 2048位RSA加密后密文固定256字节,初始化对应大小的缓冲区
    std::vector<unsigned char> vecBlock(256);
    memcpy(vecBlock.data(), plaintext.data(), plaintextLen);
    DWORD dwEncryptedLen = plaintextLen;

    // 执行加密操作
    bReturn = CryptEncrypt(hCryptKey, NULL, TRUE, 0, vecBlock.data(), &dwEncryptedLen, vecBlock.size());
    if (!bReturn) break;

    // 保存加密结果
    std::vector<unsigned char> vecResult(vecBlock.begin(), vecBlock.begin() + dwEncryptedLen);

} while (FALSE);

// 释放资源
if (hCryptKey) CryptDestroyKey(hCryptKey);
if (hCryptProv) CryptReleaseContext(hCryptProv, 0);

2. 修正C#解密代码

添加输入验证与错误处理,确保密钥与密文格式正确:

public static byte[] RSA_Decrypt(byte[] inputData, byte[] privateKey)
{
    // 验证密文长度:2048位RSA密文必须为256字节
    if (inputData == null || inputData.Length != 256)
        throw new ArgumentException("输入密文长度不符合要求");

    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048))
    {
        try
        {
            rsa.ImportCspBlob(privateKey);
            // false对应PKCS#1 v1.5填充,与C++默认填充一致
            return rsa.Decrypt(inputData, false);
        }
        catch (CryptographicException ex)
        {
            throw new InvalidOperationException("解密失败", ex);
        }
    }
}

3. 关键验证事项

  • 密钥配对:确保C++使用的公钥与C#使用的私钥属于同一RSA密钥对,可通过C#生成密钥对后,分别导出公钥、私钥Blob供两端使用。
  • 填充模式:两端默认均使用PKCS#1 v1.5填充,无需额外配置。
  • 数据长度:加密后密文长度固定为256字节,解密前必须验证输入数据长度,避免参数错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:01:17