C# 在C中复制Ruby OpenSSL私有加密输出#
我有一个简单的Ruby脚本,我正在使用它对一些HTTP头进行私有加密,以对发送到Ruby REST API的web请求进行签名。该API根据它生成的Base64编码字符串测试Base64编码字符串,而不是解码Base64并解密数据,然后测试原始字符串 我使用的脚本是C# 在C中复制Ruby OpenSSL私有加密输出#,c#,ruby,encryption,openssl,rsa,C#,Ruby,Encryption,Openssl,Rsa,我有一个简单的Ruby脚本,我正在使用它对一些HTTP头进行私有加密,以对发送到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_k
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抛出并捕获标准输出,虽然这不是一个主要问题,但我希望消除对ruby的依赖,但我无法使用C#rsacryptServiceProvider重现输出
如果我使用ruby对“SimpleString”的私有加密结果进行Base64编码,我会得到一致的结果
auReJzoPSW3AhzsfT3EH4rD7lc4y2CJ026xIOiV6kjl2OKIj8GnzrPosoJDg\nSHRVKRSXYLEGGJRmX+vaAHSAm7RXrZh5An2SnVuO3qITa2TJ78hTc3bAw\nCDm4i9/4QICTJXEFNPRE6
EYCa4b3dnM5moa1eo9zbQPBa1eS6ItRCX4C0G0\N1TJPQSEVUUMS363EAHTUAYA6YEWINLPME0USW6JFFNNSXW8NV9SNC+ziomb\n/mwlt9dS5/mzKM8yFMH6hdQYLoqc0QpjT+XAZYJ6DG5MVG
h3JtjIVRTOSd\n+pUU/bo+obEHbrftG8u2uJImLSA+/1e8aapHaa3WNg==
使用.Net时
RsaCryptoServiceProvider.Encrypt("SimpleString", false)
由于使用公钥进行加密,因此结果总是不同的输出
我也试过了
RsaCryptoServiceProvider.SignData
虽然这总是产生相同的结果,但它与ruby的结果不同
我可以直接从.Net使用一些CryptoAPI来实现与Ruby相同的结果吗?您可以使用私钥进行加密 这里至少有一个这样做的例子:
请注意在进行加密时使用PrivateKey属性(尽管本文引用了解密,但您也可以对加密执行相同的操作)为什么不使用?它提供了完整的加密框架,并且有一个类可以从PEM文件加载X509证书。您需要的是生成“原始签名”的方法。原始签名通常包括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()));
}
之后,
rsadgestsigner
类将使用DigestInfo
中的EncodeBlock
方法生成PKCS#1填充。NullDigest
不做任何事情,它只返回作为自身签名提供给它的数据。您只想使用BCL吗?因为你可以用BouncyCastle来做。抱歉,在BCL中没有办法使用私钥进行加密。SignData会创建一个数据散列,不是用来解密的。我想这样做,但我几乎得出结论,使用BCL是不会发生的,只要解决方案完全基于.Net,并且消除了对Ruby的依赖,那么第三方组件就可以了。我要去看看蹦蹦跳跳的城堡!谢谢。你不会想在C#重新创建厨师休息电话吧?你找到解决方案了吗?我尝试了许多不同的示例,但RSACryptServiceProvider无法满足我的要求,它只能使用私钥进行签名,而不能进行加密,签名会创建一个散列并加密,从而为所需内容提供不同的输出。更不用说我没有幸使用RSACryptServiceProvider或X509Certificate加载PEM文件(2),我必须通过手动加载字节级别的文件来实现这一点!这不起作用,这将使用PKCS#1 v1.5格式用于加密,而不是用于签名。回答有点晚,我只是查看一些旧问题的日志…虽然使用Bouncy始终是一个好主意来使用执行较低级别的加密API,但我认为这个答案不足以解决给定的问题。