我有一个简单的Ruby脚本,用于在某些HTTP头上执行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重现输出。
如果我Base64使用ruby编码“SimpleString”的private_encrypt结果我一直得到
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相同的结果吗?
答案 0 :(得分:1)
您需要的是一种生成“原始签名”的方法。原始签名通常包括PKCS#1 v1.5兼容签名格式的模幂运算,但也可以使用其他填充方法。与正常签名操作的区别在于不执行任何散列,并且 - 在PKCS#1 v1.5兼容签名格式的情况下 - 不会在散列周围创建ASN.1结构value,用于标识所使用的散列方法。
此原始签名格式不是生成签名的标准化方法,应避免使用 。 private_encrypt
主要用于支持已弃用的SSL版本,该版本使用该方法使用MD5和SHA1哈希值的原始输出的串联来创建身份验证签名。
最后,正如Siva建议的那样,您可以使用Bouncy Castle C#库来创建原始签名格式。由于第二段中给出的原因,大多数更高级API都不支持原始签名格式。
[EDIT2]为此,您需要使用原始的“RSA”功能。
if (mechanism.Equals("RSA"))
{
return (new RsaDigestSigner(new NullDigest()));
}
之后,RsaDigestSigner
类将使用EncodeBlock
中的DigestInfo
方法生成PKCS#1填充。 NullDigest
没有做任何事情,只是将给定的数据作为自身的签名返回。
答案 1 :(得分:0)
为什么不使用Bouncy Castle C#?它提供了完整的加密框架,并且有从PEM文件加载X509Certificate的类。
答案 2 :(得分:-1)
您可以使用私钥进行加密。
这是至少一个这样做的例子:
http://www.csharpbydesign.com/2008/04/asymmetric-key-encryption-with.html
请注意在执行加密时使用PrivateKey属性(尽管文章引用了 decryption ,您也可以对加密执行相同操作)