DSA 签名 c#

DSA signature c#

Certificate我有证书

这是我要验证的文本:

B5080F731EE89EC82FD2E8B22E9_I_CANNOT_SHOW_THE_REAL_TEXT

这是签名:

MIIBUwYJKoZIhvcNAQcCoIIBRDCCAUACAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGCAR8wggEbAgEBMG8wZDELMAkGA1UEBhMCREUxHDAaBgNVBAoTE1NBUCBUcnVzdCBDb21tdW5pdHkxEzARBgNVBAsTClNBUCBXZWIgQVMxFDASBgNVBAsTC0kwMDIwMjEyMzYwMQwwCgYDVQQDEwNFMTUCByASBQYIEQgwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE4MDYyNzE5MzcyNVowIwYJKoZIhvcNAQkEMRYEFDgpp0877pKaChyIGVw5sPeD0W03MAkGByqGSM44BAMEMDAuAhUA4PH8bdBPHHtuPHvhJxjei%2BFrJYUCFQCnZ6IABDiRlctS9E9N3IQK60JLIg%3D%3D

找不到使用 C# 验证签名的方法。当我使用 "normal" DSACryptoServiceProvider 时,我总是收到错误消息,指出签名大小应为 40 字节。

我只需要知道我们要去哪里。值得使用 我知道是DSA。 我知道签名大约有 500 字节

这是我正在尝试的代码:

DSACryptoServiceProvider csp = (DSACryptoServiceProvider)CurrentCer.csp.PublicKey.Key;

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

var base64EncodedBytes = System.Convert.FromBase64String(signature);
result = csp.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), base64EncodedBytes);

DSASignatureDeformatter verifier = new DSASignatureDeformatter(csp);
verifier.SetHashAlgorithm("SHA1");
bool valid = verifier.VerifySignature(hash, base64EncodedBytes);

您的数据本身并不是签名。它是具有分离内容的 CMS 签名数据的查询字符串编码的 base64 编码表示,并且恰好已使用 DSA 签名。

str = Uri.UnescapeDataString(str);
byte[] signatureMessage = Convert.FromBase64String(str);
ContentInfo content = new ContentInfo(yourDataHere);
SignedCms signedCms = new SignedCms(content, detached: true);
signedCms.Decode(signatureMessage);

SignerInfoCollection signers = signedCms.SignerInfos;

if (signers.Count != 1 || signers[0].Certificate != null)
{
    // Reject it, this isn't what you're looking for.
    // At least, based on the sample you gave.
    //
    // You could, for Count == 1, accept Certificate == null or
    // Certificate.RawData.SequenceEqual(CurrentCer.RawData),
    // if you're so inclined.
}

// This throws if the signature doesn't check out.
signedCms.CheckSignature(new X509Certificate2Collection(CurrentCer), verifySignatureOnly: true);