c# - 在 C# 中重现 Ruby OpenSSL private_encrypt 输出

标签 c# ruby encryption openssl rsa

我有一个简单的 Ruby 脚本,我用它在某些 HTTP header 上执行 private_encrypt 以签署要发送到 ruby​​ REST API 的 Web 请求,该 API 会根据 Base64 编码字符串测试 Base64 编码字符串生成而不是解码 Base64 和解密数据然后测试原始字符串。

我使用的脚本是

require "openssl"
require "base64"

path_to_cert = ARGV[0].dup

plain_text = Base64.decode64(ARGV[1].dup)

private_key = OpenSSL::PKey::RSA.new(File.read(path_to_cert))

puts Base64.encode64(private_key.private_encrypt(plain_text))

输入是 Base64 编码的事实纯粹是由于输入参数中的换行符和空格。

要使用它,我必须使用 System.Diagnostics.Process 处理 ruby​​ 并捕获 StdOut,虽然这不是主要问题并且可以工作,但我想删除对 ruby​​ 的依赖,但我无法使用 C# RsaCryptoServiceProvider 重现输出。

如果我使用 ruby​​ 对“SimpleString”的 private_encrypt 结果进行 Base64 编码,我始终得到

auReJzoPSW3AhzsfT3EH4rD7lc4y2CJ026xIOiV6kjl2OKIj8GnzrPosoJDg\nSHrvLVKrSxYlegYgJRMx+vaAHSAm7RXrZh5An2SnVuO3qITa2TJ78hTc3bAw\nCDm4i9/4qictjxEFfnPRe6 EYCa4b3dnM5moa1eo9zbQPBa1eS6ItRCX4C0G0\n1tJpQsEvuums363eAhTUAYa6yEWuINLPmE0USW6jfFNnsxw8Nv9SnC+ziomb\n/mwlt9dS5/mzKM8yFMH6hdQYLoqc0QpjT+xaZ1ZyJ6dG5MVG h3JtjIVRTOSd\n+pUU/bo+obEHbrftG8u2uJImLSA+/1e8aapHaa3WNg==

使用 .Net 时

RsaCryptoServiceProvider.Encrypt("SimpleString", false) 

结果总是不同的输出,因为它是用公钥加密的。

我也试过

RsaCryptoServiceProvider.SignData

虽然这总是产生相同的结果,但它与 ruby​​ 的结果不同。

我可以直接从 .Net 使用一些 CryptoAPI 来实现与 Ruby 相同的结果吗?

最佳答案

您需要的是一种生成“原始签名”的方法。原始签名通常由 PKCS#1 v1.5 兼容签名格式的模幂组成,尽管也可以使用其他填充方法。与普通签名操作的区别在于它执行任何散列,并且 - 在 PKCS#1 v1.5 兼容签名格式的情况下 - 不围绕散列创建 ASN.1 结构值,用于标识所使用的哈希方法。

这种原始签名格式不是生成签名的标准方法,应该避免private_encrypt 主要用于支持已弃用的 SSL 版本,该版本使用 MD5 和 SHA1 哈希值的原始输出的串联来创建用于身份验证的签名。

最后,正如 Siva 所建议的,您可以使用 Bouncy CaSTLe C# 库来创建原始签名格式。由于第二段中给出的原因,大多数更高级别的 API 不直接支持原始签名格式。

[EDIT2] 为此,您需要使用原始的“RSA”功能。

if (mechanism.Equals("RSA"))
{
    return (new RsaDigestSigner(new NullDigest()));
}

之后 RsaDigestSigner 类将使用 DigestInfo 中的 EncodeBlock 方法生成 PKCS#1 填充。 NullDigest 不会什么都不做,它只是返回给它的数据作为它自己的签名。

关于c# - 在 C# 中重现 Ruby OpenSSL private_encrypt 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5579665/

相关文章:

c# - 如何在 Delphi 中使用密码 AES-128 加密字符串并在 C# 中解密?

包含多种类型的类型列表的 c# MVC Entity Framework 模型属性

ruby - 根据用户输入循环创建

ruby-on-rails - 多态关联 foreign_type 使用 STI 类设置祖先类型而不是当前类型

java - 使用 AES(128) 对音频/视频文件进行加密和解密

swift - 如何在 macOS 上正确存储加密 key 以便只有我的可执行文件可以访问它们?

c# - 单元测试构造函数注入(inject)

c# - Java 的 SecretKeySpec 类的 .NET 等效项是什么?

c# - 测试依赖于其他属性的属性的自定义验证会返回 ArgumentNullException

ruby - 为什么\d+ 不匹配所有数字?