C# 用公钥验证数据(用 RSA 私钥签名)

发布于 2024-11-24 07:22:19 字数 1493 浏览 2 评论 0原文

使用 BouncyCastle 并在 stackoverflow 问题的帮助下我得到了这个:

        using System.Net.Sockets;
        using System.Security.Cryptography;
        using Org.BouncyCastle.Crypto.Parameters;
        using Org.BouncyCastle.OpenSsl;

...

        TcpClient client = new TcpClient("127.0.0.1", 1337);
        NetworkStream stream = client.GetStream();

        StreamWriter writer= new StreamWriter(stream);
        StreamReader reader = new StreamReader(stream);

        writer.WriteLine("hello");
        writer.AutoFlush = true;

        string response = Convert.FromBase64String(reader.ReadToEnd()).ToString();

        RSACryptoServiceProvider RCP;
        var x = new PemReader(File.OpenText(pubkey));
        var y = (RsaKeyParameters)x.ReadObject();

        RCP = (RSACryptoServiceProvider)RSACryptoServiceProvider.Create();

        var pa = new RSAParameters();
        pa.Modulus = y.Modulus.ToByteArray();
        pa.Exponent = y.Exponent.ToByteArray();

        RCP.ImportParameters(pa);
        byte[] test = RCP.Decrypt(response, true);

现在,显然解密会失败,因为我试图解密已签名(不是“加密”)的东西并且肯定不是由相同的“密钥” 。我很困惑,因为我认为我应该使用类似 VerifyData(),但这返回一个布尔值并接受我不确定的参数。

我希望完成的是 Openssl rsautl -verify -inkey public.pem -pubin 的 C# 等效项。也就是说,用公钥“解密”以验证所述消息的内容。

我走在正确的轨道上吗?

  • 米克

using BouncyCastle and with help from a stackoverflow question I got this:

        using System.Net.Sockets;
        using System.Security.Cryptography;
        using Org.BouncyCastle.Crypto.Parameters;
        using Org.BouncyCastle.OpenSsl;

...

        TcpClient client = new TcpClient("127.0.0.1", 1337);
        NetworkStream stream = client.GetStream();

        StreamWriter writer= new StreamWriter(stream);
        StreamReader reader = new StreamReader(stream);

        writer.WriteLine("hello");
        writer.AutoFlush = true;

        string response = Convert.FromBase64String(reader.ReadToEnd()).ToString();

        RSACryptoServiceProvider RCP;
        var x = new PemReader(File.OpenText(pubkey));
        var y = (RsaKeyParameters)x.ReadObject();

        RCP = (RSACryptoServiceProvider)RSACryptoServiceProvider.Create();

        var pa = new RSAParameters();
        pa.Modulus = y.Modulus.ToByteArray();
        pa.Exponent = y.Exponent.ToByteArray();

        RCP.ImportParameters(pa);
        byte[] test = RCP.Decrypt(response, true);

Now, obviously Decrypt will fail, as since I'm trying to decrypt something which was signed (not "encrypted") and definately not by the same "key". I'm confused since I thought I should use a method like VerifyData(), but this returns a bool and takes arguments I'm not sure I have.

What I wish to accomplish is the C# equivalent of openssl rsautl -verify -inkey public.pem -pubin. That is, "decrypt" with the pubkey to verify the contents of said message.

Am I on the right track here?

  • Mik

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

和我恋爱吧 2024-12-01 07:22:19

实际上,除非您指定了错误的编码参数,否则签名的解密永远不会失败 - 签名只是数据的私钥加密哈希(通常为 SHA1);使用验证例程的唯一好处是它解密块并为您进行哈希比较,如果您想变得更大胆,您可以使用您的公钥进行解密操作并自己比较哈希字节。

我实际上不确定您的程序上下文中的响应是什么;你应该将RSA数据传递给它,如果你还向它提供最初签名的数据,那么你做错了 - 同样,做检查该函数是否确实接受字符串,根据我的经验,BouncyCastle 通常需要一个 byte[]

我建议使用 SignerUtilities.GetSigner() - 它需要一个字符串 arg告诉它什么样的签名如果您正在使用,我想 "SHA1WithRSA" 适合您。

Actually a decrypt of a signature should never fail unless you specified the wrong encoding parameters - a signature is simply the private-key encrypted hash of the data (typically SHA1); the only benefit of using the verify routine is that it decrypts the block and does the hash comparison work for you, if you wanted to be bloody minded you could instead do a decrypt operation with your public key and compare the hash bytes yourself.

I'm not actually sure what response is in the context of your program; you should only be passing the RSA data to it, if you're also feeding it the data that was signed in the first place you are doing it wrong - similarly, do check if that function actually accepts a string, in my experience BouncyCastle generally expects a byte[]

I'd recommend using SignerUtilities.GetSigner() - it takes a string arg to tell it what sort of signature you're using, I would imagine "SHA1WithRSA" to be right for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文