Xamarin PCLCrypto RSACryptoServiceProvider SignData эквивалент
В настоящее время я работаю с PCLCrypto и искал способ имитировать функцию SignData System.Security.Cryptography.RSACryptoServiceProvider. В настоящее время я использую этот код для создания:
var mac = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithm.RsaSignPkcs1Sha512);
var cryptoKey = mac.CreateKeyPair(2048);
var hash = WinRTCrypto.CryptographicEngine.Sign(cryptoKey, input);
return WinRTCrypto.CryptographicBuffer.EncodeToBase64String(hash);
Это код, который я использую для проверки подписи:
var mac = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithm.RsaSignPkcs1Sha512);
var keyMaterial = WinRTCrypto.CryptographicBuffer.ConvertStringToBinary(key, Encoding.UTF8);
var cryptoKey = mac.ImportPublicKey(keyMaterial, CryptographicPublicKeyBlobType.X509SubjectPublicKeyInfo);
return WinRTCrypto.CryptographicEngine.VerifySignature(cryptoKey, data, signature);
Чтобы быть ясным, я на 100% уверен, что я использую правильную пару ключей. Мой ключ находится в следующем формате:
<RSAKeyValue><Modulus>nMhF8TRjT5O7tTtqr1//9ahokRuNGRxdGwc7fwk+i21Zscr/7L0PlfiE/sTQC/VQrj/BHhkX8CXVMTw1ukSN7zZDD7UCbdvhmV7jhPs/TDJP70Y4pgcG624WnQXjWDgR5f7Mbfg18zsevidtGukK+U5huaBfxhxg2Za3X3JzUYc=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
Может кто-нибудь указать мне на пример, который производит тот же вывод, что и RSACryptoServiceProvider?
1 ответ
Я на самом деле понял это сам, очевидно, у него были некоторые проблемы с импортом ключа, который был указан в формате xml. Мое текущее решение, которое дает желаемый результат:
public static class CryptographyExtensions
{
private static readonly String ModulusStartString = "<Modulus>";
private static readonly String ModulusEndString = "</Modulus>";
private static readonly String ExponentStartString = "<Exponent>";
private static readonly String ExponentEndString = "</Exponent>";
private static readonly String PStartString = "<P>";
private static readonly String PEndString = "</P>";
private static readonly String QStartString = "<Q>";
private static readonly String QEndString = "</Q>";
private static readonly String DPStartString = "<DP>";
private static readonly String DPEndString = "</DP>";
private static readonly String DQStartString = "<DQ>";
private static readonly String DQEndString = "</DQ>";
private static readonly String DStartString = "<D>";
private static readonly String DEndString = "</D>";
private static readonly String InverseQStartString = "<InverseQ>";
private static readonly String InverseQEndString = "</InverseQ>";
public static RSAParameters ConvertPrivateKeyFromString(String privateKey)
{
var rsaparams = new RSAParameters()
{
Modulus = Convert.FromBase64String(privateKey.Substring(ModulusStartString, ModulusEndString)),
Exponent = Convert.FromBase64String(privateKey.Substring(ExponentStartString, ExponentEndString)),
P = Convert.FromBase64String(privateKey.Substring(PStartString, PEndString)),
Q = Convert.FromBase64String(privateKey.Substring(QStartString, QEndString)),
DP = Convert.FromBase64String(privateKey.Substring(DPStartString, DPEndString)),
DQ = Convert.FromBase64String(privateKey.Substring(DQStartString, DQEndString)),
D = Convert.FromBase64String(privateKey.Substring(DStartString, DEndString)),
InverseQ = Convert.FromBase64String(privateKey.Substring(InverseQStartString, InverseQEndString))
};
return rsaparams;
}
public static RSAParameters ConvertPublicKeyFromString(String publicKey)
{
var rsaparams = new RSAParameters()
{
Modulus = Convert.FromBase64String(publicKey.Substring(ModulusStartString, ModulusEndString)),
Exponent = Convert.FromBase64String(publicKey.Substring(ExponentStartString, ExponentEndString))
};
return rsaparams;
}
public static class RsaEncryption
{
public static string HashAndSign(byte[] input, string key)
{
var mac = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithm.RsaSignPkcs1Sha512);
var cryptoKey = mac.ImportParameters(CryptographyExtensions.ConvertPrivateKeyFromString(key));
var hash = WinRTCrypto.CryptographicEngine.Sign(cryptoKey, input);
return WinRTCrypto.CryptographicBuffer.EncodeToBase64String(hash);
}
public static bool VerifySignature(byte[] data, byte[] signature, string key)
{
var mac = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithm.RsaSignPkcs1Sha512);
var cryptoKey = mac.ImportParameters(CryptographyExtensions.ConvertPublicKeyFromString(key));
return WinRTCrypto.CryptographicEngine.VerifySignature(cryptoKey, data, signature);
}
}
public static class StringExtensions
{
public static string Substring(this string @this, string from = null, string until = null, StringComparison comparison = StringComparison.OrdinalIgnoreCase)
{
var fromLength = (from ?? string.Empty).Length;
var startIndex = !string.IsNullOrEmpty(from)
? @this.IndexOf(from, comparison) + fromLength
: 0;
if (startIndex < fromLength) { throw new ArgumentException("from: Failed to find an instance of the first anchor"); }
var endIndex = !string.IsNullOrEmpty(until)
? @this.IndexOf(until, startIndex, comparison)
: @this.Length;
if (endIndex < 0) { throw new ArgumentException("until: Failed to find an instance of the last anchor"); }
var subString = @this.Substring(startIndex, endIndex - startIndex);
return subString;
}
}