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

RSA加解密系统OAEP填充解密错误修复求助

修复RSA OAEP填充解密错误

问题根源

你的代码中GenerateKeys方法创建了两个独立的RSA实例,分别导出公钥和私钥——这两组密钥完全不配对。用这个公钥加密的数据,自然无法用另一个无关的私钥解密,直接导致OAEP填充验证失败。

修复步骤

  1. 使用同一个RSA实例生成密钥对:密钥对必须由同一个RSA对象生成,才能保证公钥和私钥匹配。
  2. 完善密钥显示逻辑:私钥包含更多参数(如D、P、Q等),原GetKeyString方法只显示公钥参数,需要补充私钥的信息展示。
  3. 推荐使用现代RSA API:RSACryptoServiceProvider是旧版API,替换为RSA.Create()可获得更好的兼容性和安全性。

完整修正代码

using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;
using System.Windows.Forms;

namespace RSA
{
    public partial class Form1 : Form
    {
        private RSAParameters publicKey;
        private RSAParameters privateKey;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            GenerateKeys();
            publicKeyLabel.Text = GetKeyString(publicKey, isPrivateKey: false);
            privateKeyLabel.Text = GetKeyString(privateKey, isPrivateKey: true);
        }

        // 修复:用同一个RSA实例生成配对的密钥对
        private void GenerateKeys()
        {
            using (RSA rsa = RSA.Create(2048)) // 推荐使用2048位及以上密钥长度
            {
                publicKey = rsa.ExportParameters(false);
                privateKey = rsa.ExportParameters(true);
            }
        }

        // 完善:支持显示公钥/私钥的完整参数
        static string GetKeyString(RSAParameters key, bool isPrivateKey)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"模数(n): {BitConverter.ToString(key.Modulus).Replace("-", "")}");
            sb.AppendLine($"指数(e): {BitConverter.ToString(key.Exponent).Replace("-", "")}");

            if (isPrivateKey)
            {
                sb.AppendLine($"私钥指数(d): {BitConverter.ToString(key.D).Replace("-", "")}");
                sb.AppendLine($"素数p: {BitConverter.ToString(key.P).Replace("-", "")}");
                sb.AppendLine($"素数q: {BitConverter.ToString(key.Q).Replace("-", "")}");
                sb.AppendLine($"d mod (p-1): {BitConverter.ToString(key.DP).Replace("-", "")}");
                sb.AppendLine($"d mod (q-1): {BitConverter.ToString(key.DQ).Replace("-", "")}");
                sb.AppendLine($"逆元q mod p: {BitConverter.ToString(key.InverseQ).Replace("-", "")}");
            }
            return sb.ToString();
        }

        private void buttonChooseFile_Click(object sender, EventArgs e)
        {
            string filePath = GetFilePath();
            if (!string.IsNullOrEmpty(filePath))
            {
                string textToEncrypt = File.ReadAllText(filePath);
                originalTextLabel.Text = $"原始文本: {textToEncrypt}";
            }
        }

        private void buttonEncrypt_Click(object sender, EventArgs e)
        {
            string textToEncrypt = originalTextLabel.Text.Replace("原始文本: ", "");
            if (!string.IsNullOrEmpty(textToEncrypt))
            {
                string encryptedText = EncryptText(textToEncrypt, publicKey);
                encryptedTextLabel.Text = $"加密文本: {encryptedText}";
            }
        }

        private string GetFilePath()
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*";
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    return openFileDialog.FileName;
                }
                else
                {
                    return null;
                }
            }
        }

        // 替换为现代RSA API
        private string EncryptText(string text, RSAParameters publicKey)
        {
            using (RSA rsa = RSA.Create())
            {
                rsa.ImportParameters(publicKey);
                byte[] encryptedBytes = rsa.Encrypt(Encoding.UTF8.GetBytes(text), RSAEncryptionPadding.OaepSHA1);
                return Convert.ToBase64String(encryptedBytes);
            }
        }

        // 替换为现代RSA API
        private string DecryptText(string encryptedText, RSAParameters privateKey)
        {
            using (RSA rsa = RSA.Create())
            {
                rsa.ImportParameters(privateKey);
                byte[] encryptedBytes = Convert.FromBase64String(encryptedText);
                byte[] decryptedBytes = rsa.Decrypt(encryptedBytes, RSAEncryptionPadding.OaepSHA1);
                return Encoding.UTF8.GetString(decryptedBytes);
            }
        }

        private void buttonDecrypt_Click(object sender, EventArgs e)
        {
            string encryptedText = encryptedTextLabel.Text.Replace("加密文本: ", "");
            if (!string.IsNullOrEmpty(encryptedText))
            {
                string decryptedText = DecryptText(encryptedText, privateKey);
                decryptedTextLabel.Text = $"解密文本: {decryptedText}";
            }
        }
    }
}

额外注意事项

  • 密钥长度:1024位RSA密钥已被认为不安全,建议使用2048位或4096位。
  • 填充一致性:加密和解密必须使用相同的填充模式(此处为OaepSHA1),如果更换哈希算法(如SHA256),需两边同步修改。
  • 文本处理:RSA仅适合加密小数据(如对称密钥),若需加密大文本,建议先用AES等对称算法加密数据,再用RSA加密对称密钥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 20:14:51