Для связи между приложением ac # dotnet-core (windows и linux) и Chef.io API мне нужно иметь возможность создать такую же сигнатуру в ядре c # dotnet, как этот вызов исполняемого файла openssl:
openssl rsautl -in encryption.txt -sign -inkey chefprivatekey.pem |openssl enc -base64
Первая реализация (dotnet framework) была основана на этом 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, все работает нормально, но если я обновлю dll до более новой версии, используя для этого пакет nuget, то ничего больше не будет работать. В качестве обходного пути я реализовал системный вызов исполняемого файла openssl, чтобы получить правильную сигнатуру для API. Это отлично работает. Но мне нужно избавиться от системных вызовов. Сейчас я сравнил результат системного вызова openssl exe с результатами, полученными из любых алгоритмов подписания, таких как BouncyCastle lib. Я не смог получить тот же результат, что и вышеупомянутый вызов openssl-exe. Реализация должна быть dotnet-core для Windows и Linux. Поскольку результаты между openssl exe и любой реализацией на c # не совпадают, я не буду тестировать chef-api. Мне удалось создать System.Security.Cryptography.RSACryptoServiceProvider из файла pem, следуя этому примеру: Как загрузить открытый ключ RSA из файла в C # . с помощью этого кода я могу получить объект типа RSACryptoServiceProvider из файла pem.
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, может ли это быть проблемой?