如何比较 .NET 中的公钥?

发布于 2025-01-03 11:21:20 字数 621 浏览 1 评论 0原文

我有一个 X509Certificate2包含公钥。我有一个 RSACryptoServiceProvider (来自调用 SignedXml.CheckSignatureReturningKey),还包含公钥。

我想知道其中一个是否来自另一个。我如何比较两者?

I've got an X509Certificate2 containing a public key. I've got an RSACryptoServiceProvider (which came from calling SignedXml.CheckSignatureReturningKey), also containing a public key.

I want to find out if one came from the other. How can I compare the two?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

九命猫 2025-01-10 11:21:20

您可以比较 PublicKey 中签名证书的属性href="https://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=EN-US&k=k(System.Security.Cryptography.Xml.SignedXml.KeyInfo);k(KeyInfo) ;k(TargetFrameworkMoniker-.NETFramework,版本%3Dv4.5.2);k(DevLang-csharp)&rd=true" rel="nofollow">SignedXml.KeyIfo 带有来自 SignedXml.CheckSignatureReturningKey。这个 C# 扩展方法为我完成了这项工作:

public static bool CheckSignatureReturningCertificate(this SignedXml signedXml, out X509Certificate2 signingCertificate)
{
    signingCertificate = null;
    AsymmetricAlgorithm signingKey;
    bool isValid = signedXml.CheckSignatureReturningKey(out signingKey);
    if (isValid)
    {
        IEnumerable<X509Certificate2> keyInfoCertificates =
            signedXml.KeyInfo.OfType<KeyInfoX509Data>()
                .SelectMany(x => x.Certificates.Cast<X509Certificate2>());

        signingCertificate = keyInfoCertificates.FirstOrDefault(x => x.PublicKey.Key == signingKey);
        if (signingCertificate == null)
        {
            throw new Exception("Signing certificate not found in KeyInfo.");
        }
    }

    return isValid;
}

像这样使用它:

X509Certificate2 signingCertificate = null;
bool isValid = signedXml.CheckSignatureReturningCertificate(out signingCertificate);
if(isValid)
{
    // signingCertificate now contains the certificate used to sign
}

You can compare the PublicKey property of signing certificates in the SignedXml.KeyIfo with signing key output from SignedXml.CheckSignatureReturningKey. This C# extension method does the job for me:

public static bool CheckSignatureReturningCertificate(this SignedXml signedXml, out X509Certificate2 signingCertificate)
{
    signingCertificate = null;
    AsymmetricAlgorithm signingKey;
    bool isValid = signedXml.CheckSignatureReturningKey(out signingKey);
    if (isValid)
    {
        IEnumerable<X509Certificate2> keyInfoCertificates =
            signedXml.KeyInfo.OfType<KeyInfoX509Data>()
                .SelectMany(x => x.Certificates.Cast<X509Certificate2>());

        signingCertificate = keyInfoCertificates.FirstOrDefault(x => x.PublicKey.Key == signingKey);
        if (signingCertificate == null)
        {
            throw new Exception("Signing certificate not found in KeyInfo.");
        }
    }

    return isValid;
}

Use it like this:

X509Certificate2 signingCertificate = null;
bool isValid = signedXml.CheckSignatureReturningCertificate(out signingCertificate);
if(isValid)
{
    // signingCertificate now contains the certificate used to sign
}
淡淡離愁欲言轉身 2025-01-10 11:21:20

RSA 算法的公钥参数是{e, n}、指数和模数。在 .NET 中,可以从 RSAParameters 结构。其他字段代表私钥。

因此,要比较 X509Certificate2RSACryptoServiceProvider 的公钥相等性,您只需获取以下参数:

AsymmetricAlgorithm signingKey;
bool signatureIsVerified = signedXml.CheckSignatureReturningKey(out signingKey);

var certificateParameters =
    ((RSA)certificate.PublicKey.Key).ExportParameters(
        includePrivateParameters: false);
var signingParameters = signingKey.ExportParameters(
        includePrivateParameters: false);
bool areEqual =
    ByteArrayEquals(certificateParameters.Exponent,
                    signingParameters.Exponent)
    && ByteArrayEquals(certificateParameters.Modulus,
                    signingParameters.Modulus);

您必须实现 ByteArrayEquals,因为在 .NET 中没有好的方法

如果您使用 DSA 而不是 RSA,则公钥由 {p, q, g, y} 组成。

The public key parameters for the RSA algorithm are {e, n}, the exponent and the modulus. In .NET, these are available from the RSAParameters struct. The other fields represent the private key.

So, to compare an X509Certificate2 and an RSACryptoServiceProvider for public key equality, you can just grab these parameters:

AsymmetricAlgorithm signingKey;
bool signatureIsVerified = signedXml.CheckSignatureReturningKey(out signingKey);

var certificateParameters =
    ((RSA)certificate.PublicKey.Key).ExportParameters(
        includePrivateParameters: false);
var signingParameters = signingKey.ExportParameters(
        includePrivateParameters: false);
bool areEqual =
    ByteArrayEquals(certificateParameters.Exponent,
                    signingParameters.Exponent)
    && ByteArrayEquals(certificateParameters.Modulus,
                    signingParameters.Modulus);

You'll have to implement ByteArrayEquals, because there's no good way to do it in .NET.

If you're using DSA rather than RSA, the public key is made up of {p, q, g, y}.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文