Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中复制Ruby OpenSSL私有加密输出#_C#_Ruby_Encryption_Openssl_Rsa - Fatal编程技术网

C# 在C中复制Ruby OpenSSL私有加密输出#

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

我有一个简单的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_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,但我认为这个答案不足以解决给定的问题。