需要能够从 C#(dotnet-core)代码中获取与 openssl rsautl -sign -inkey 相同的签



对于 c# dotnet核心应用程序(Windows 和 linux(和 Chef.io API 之间的通信,我需要能够在 c# dotnet core 中创建与 openssl 可执行文件调用相同的签名:

OpenSSL rsautl -in encryption.txt -sign -inkey chefprivatekey.pem | openssl enc -base64

第一个实现(dotnet 框架(基于此 https://github.com/mattberther/dotnet-chef-api:

byte[] input = Encoding.UTF8.GetBytes(canonicalHeader);
var pemReader = new PemReader(new StringReader(privateKey));
AsymmetricKeyParameter key = ((AsymmetricCipherKeyPair)pemReader.ReadObject()).Private;
ISigner signer = new RsaDigestSigner(new NullDigest());
signer.Init(true, key);
signer.BlockUpdate(input, 0, input.Length);
_signature = Convert.ToBase64String(signer.GenerateSignature());

nuget 包 dotnet-chef-api 还包含旧版本的 BouncyCastle.Crypto.dll。只要我使用此 dll 就可以正常工作,但是如果我为此使用 nuget 包将 dll 更新到较新的版本,则不再起作用。作为一种解决方法,我已经实现了openssl可执行文件的系统调用,以获取API的正确签名。这工作正常。但是我需要摆脱系统调用。 我现在所做的是将openssl exe的系统调用结果与我从任何签名算法(如BouncyCastle lib(获得的结果进行比较。我无法获得与上述openssl-exe调用相同的结果。对于Windows和Linux,实现必须是dotnet核心。 只要 openssl exe 和任何 c# 实现之间的结果不同,我就不会测试 chef-api。 我能够从 pem 文件创建 System.Security.Cryptography.RSACryptoServiceProvider,例如:如何在 C# 中从文件加载 RSA 公钥。 有了这段代码,我可以从 pem 文件中获取一个 RSACryptoServiceProvider 类型的对象。

RSACryptoServiceProvider provider = PemKeyUtils.GetRSAProviderFromPemFile(pemFile);
var trial1 = Convert.ToBase64String(provider.SignData(Convert.FromBase64String("test"), new SHA1CryptoServiceProvider()));
">

trial1"的内容与"_signature"相同,但与openssl的内容不同.exe 我做错了什么?

"openssl rsautl"默认使用 PKCS#1 v1.5 这可能是一个问题吗?

我自己找到了解决方案。我查看了BouncyCastle的单元测试,现在得到了一个工作解决方案:

public string Sign(byte[] input, string privateKeyPath)
{
asymmetricKeyParameter AsymmetricKeyParameterFromPrivateKeyInPemFile
// Sign the hash
IBufferedCipher c = CipherUtilities.GetCipher("RSA//PKCS1Padding");
c.Init(true, asymmetricKeyParameter);
var outBytes = c.DoFinal(input);
return Convert.ToBase64String(outBytes);
}
public AsymmetricKeyParameter AsymmetricKeyParameterFromPrivateKeyInPemFile(string privateKeyPath)
{
using (TextReader privateKeyTextReader = new StringReader(File.ReadAllText(privateKeyPath)))
{
PemReader pr = new PemReader(privateKeyTextReader);
AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pr.ReadObject();
return keyPair.Private;
}
}

最新更新