RSA使用.Net进行签名并使用OpenSSL命令进行验证

时间:2017-01-09 19:50:46

标签: c# openssl cryptography rsa

我正在尝试使用Sha1哈希和RSA使用C#签署一个简单数据,然后使用OpenSSL命令对其进行验证。

对于我的测试,我已经获取了Windows上预先存在的localhost证书。

以下是与C#一起使用的代码:

static void Main(string[] args)
{
    string sValTest = "sampledata";
    byte[] signature = Sign(sValTest, "localhost");
    string b64 = Convert.ToBase64String(signature);
    bool verified = Verify(sValTest, signature, @"pathToCer");
}

static byte[] Sign(string text, string certSubject)
{
    X509Store my = new X509Store(StoreName.My, StoreLocation.LocalMachine);
    my.Open(OpenFlags.ReadOnly);

    RSACryptoServiceProvider csp = null;
    foreach (X509Certificate2 cert in my.Certificates)
    {
        if (cert.Subject.Contains(certSubject))
        {
            csp = (RSACryptoServiceProvider)cert.PrivateKey;
            break;
        }
    }

    SHA1Managed sha1 = new SHA1Managed();
    byte[] data = Enconding.ASCII.GetBytes(text);
    byte[] hash = sha1.ComputeHash(data);

    return csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));
}

static bool Verify(string text, byte[] signature, string certPath)
{
    X509Certificate2 cert = new X509Certificate2(certPath);
    RSACryptoServiceProvider csp = RSACryptoServiceProvider)cert.PublicKey.Key;

    SHA1Managed sha1 = new SHA1Managed();
    byte[] data = Encoding.ASCII.GetBytes(text);
    byte[] hash = sha1.ComputeHash(data);

    return csp.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), signature);
}

(在该示例中,verified产生true

我将PFX的公共部分发送到我的linux计算机以及作为base 64的签名。

然后我做了以下事情:

base64 --decode sig.b64 > sig
openssl x509 -inform der -in localhost.cer  -out localhost.pem
openssl x509 -pubkey -noout -in localhost.pem > localhost.pub.pem
echo -n "sampledata" | openssl dgst -verify localhost.pub.pem -signature sig

Verification Failure结尾。

我检查了双方证书的序列号并且匹配。 为了以防万一,我还检查了两个站点中签名的md5,都清楚了。

关于哪里有明显失败的指示?

1 个答案:

答案 0 :(得分:1)

您在openssl dgst命令中缺少哈希算法标识符,默认为MD5。

你的最后一行是

echo -n "sampledata" | openssl dgst -verify localhost.pub.pem -signature sig -sha1