无法验证PyOpenSSL签名在C# [英] Can't verify PyOpenSSL signature in C#

查看:236
本文介绍了无法验证PyOpenSSL签名在C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用OpenSSL在PHP中签署和验证数据:

I can sign and verify data in PHP using 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 总是为真。

This works great for whatever data values I try. $result is always true.

然而,当我尝试使用BouncyCastle API验证C#它总是失败:

However, when I try to verify the signature in C# using the BouncyCastle APIs, it always fails:

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 总是false。我试过在两端使用SHA1而不是SHA256,我尝试了不同的编码,我试图逆转各种字节数组,以防万一有些endian问题,但无论我尝试,我不能验证PHP签名。我显然在C#方面缺少一些东西,但我不知道是什么。

No matter what I try, isValid is always false. I've tried using SHA1 on both ends instead of SHA256, I've tried different encodings, I've tried reversing various byte arrays in case there were some endian issues, but no matter what I try, I can't verify the PHP signature. I'm clearly missing something on the C# side, but I don't know what.

推荐答案

不确定什么 RSACryptoServiceProvider 对我,但我发现另一种方法完美地工作:

Well, I'm still not sure what RSACryptoServiceProvider has against me, but I found another method that works perfectly:

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;
}

这篇关于无法验证PyOpenSSL签名在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆