Не удается проверить подпись PyOpenSSL в C #

Я могу подписать и проверить данные в PHP, используя OpenSSL:

function generate_signature($privateKey, $data) {

$keyData = openssl_get_privatekey($privateKey);

openssl_sign($data, $signature, $keyData, OPENSSL_ALGO_SHA256);
openssl_free_key($keyData);

$sigText = base64_encode($signature);
return $sigText;
}

function verify_signature($pubKey, $sigText, $data) {
$signature = base64_decode($sigText);

$keyData = openssl_get_publickey($pubKey);
$ok = openssl_verify($data, $signature, $keyData, "sha256WithRSAEncryption");
openssl_free_key($keyData);

return $ok;
}

$privateKey= file_get_contents("private.key");
$pubKey = file_get_contents("public.pem");

$data = "This is a test";
$sigText = generate_signature($privateKey, $data);
$result = verify_signature($pubKey, $sigText, $data);

Это прекрасно работает для любых значений данных, которые я пытаюсь. $result всегда верно.

Однако, когда я пытаюсь проверить подпись в C # с помощью API BouncyCastle, она всегда завершается неудачей:

public static bool VerifySignature(string data, string signatureText)
{
// Using statements and error checking removed for brevity

var uri = new Uri("pack://application:,,,/Resources/public.pem");
var resourceStream = Application.GetResourceStream(uri);
var reader = new StreamReader(resourceStream.Stream);

PemReader pemReader = new PemReader(reader);
RsaKeyParameters parameters = (RsaKeyParameters)pemReader.ReadObject();
RSACryptoServiceProvider provider = (RSACryptoServiceProvider)RSACryptoServiceProvider.Create();

RSAParameters rParams = new RSAParameters();
rParams.Modulus = parameters.Modulus.ToByteArray();
rParams.Exponent = parameters.Exponent.ToByteArray();

provider.ImportParameters(rParams);

byte[] sigBytes = Convert.FromBase64String(signatureText);
byte[] dataBytes = Encoding.UTF8.GetBytes(data);

bool isValid = provider.VerifyData(dataBytes, CryptoConfig.MapNameToOID("SHA256"), sigBytes);

return isValid;
}

Что бы я ни пытался, isValid всегда ложно. Я попытался использовать SHA1 на обоих концах вместо SHA256, я пробовал разные кодировки, я пытался стереть различные байтовые массивы на случай возникновения каких-либо порядковых ошибок, но независимо от того, что я пытаюсь, я не могу проверить PHP подпись. Я явно что-то упускаю на стороне C #, но я не знаю что.

0

Решение

Ну, я все еще не уверен, что RSACryptoServiceProvider имеет против меня, но я нашел другой метод, который работает отлично:

public static bool VerifySignature(string data, string signatureText)
{
// Using statements and error checking removed for brevity
var uri = new Uri("pack://application:,,,/Resources/public.pem");
var resourceStream = Application.GetResourceStream(uri);
var reader = new StreamReader(resourceStream.Stream);

PemReader pemReader = new PemReader(reader);
RsaKeyParameters parameters = (RsaKeyParameters)pemReader.ReadObject();

RsaDigestSigner signer = (RsaDigestSigner)SignerUtilities.GetSigner("SHA-256withRSA");
signer.Init(false, parameters);

byte[] sigBytes = Convert.FromBase64String(signatureText);
byte[] dataBytes = Encoding.UTF8.GetBytes(data);

signer.BlockUpdate(dataBytes, 0, dataBytes.Length);
bool isValid = signer.VerifySignature(sigBytes);

return isValid;
}
0

Другие решения

Других решений пока нет …