验证EC签名

问题描述 投票:0回答:1

我在 Azure Key Vault 中创建了一个新密钥,其中密钥类型为 EC,曲线为 P-256。

我能够使用 EC 密钥使用 sign 操作,我也可以使用 REST API verify 它。

我现在的目标是将公钥详细信息提取为 JWK,并与无法使用 REST API 的第 3 方共享。但在分享它们之前,我试图验证这将如何在我的本地机器上运行,但我无法验证它。

这是我尝试过的代码:

// x and y points from JWK
string x = "melmeVA/KKt+kTRGljKubiohqcwD9A65dyX3nxqxUg8=";
string y = "wSOw9N8jkoeMgdNMCeAAKop4kR9f8jrvDOZnpkc9Fw0=";

ECDsa key = ECDsa.Create(new ECParameters
{
    Curve = ECCurve.NamedCurves.nistP256,
    Q = new ECPoint
    {
        X = Base64UrlEncoder.DecodeBytes(x),
        Y = Base64UrlEncoder.DecodeBytes(y)
    }
});

var header = "{\"alg\":\"ES256\"}";
var body = "{\"key\":\"value\"}";
var toBeSigned = Base64UrlEncoder.Encode(header) + "." + Base64UrlEncoder.Encode(body);

var hash = SHA256.Create();
var digest = hash.ComputeHash(Encoding.UTF8.GetBytes(toBeSigned));
Console.WriteLine(Base64UrlEncoder.Encode(digest));

// Sign API response (using the digest from above)
var signature = "ZBPn3jJpccDPasbasOfocjSkHpRA0bmn2963IMzraa50H5v5ovtavtilwpu7zf_8McwfR9qCrkXMiXBOf4W8BQ";

var publicKey = Convert.ToBase64String(key.ExportSubjectPublicKeyInfo());
Console.WriteLine(publicKey);

var result = key.VerifyData(Encoding.UTF8.GetBytes(toBeSigned), Encoding.UTF8.GetBytes(signature), HashAlgorithmName.SHA256);
Console.WriteLine(result);

我总是得到错误的结果。

c# digital-signature azure-keyvault
1个回答
0
投票

以下是基于@Topaco 评论的工作片段:

// x and y coordinates from the JWK
string x = "change_this_with_xCoordinates";
string y = "change_this_with_xCoordinates";

ECDsa key = ECDsa.Create(new ECParameters
{
    Curve = ECCurve.NamedCurves.nistP256,
    Q = new ECPoint
    {
        X = Base64UrlEncoder.DecodeBytes(x),
        Y = Base64UrlEncoder.DecodeBytes(y)
    }
});

var header = "{\"alg\":\"ES256\"}"; // the content of the header must be exactly the same as the one used at signing
var body = "{\"key\":\"value\"}"; // the content of the body must be exactly the same as the one used at signing
var toBeSigned = Base64UrlEncoder.Encode(header) + "." + Base64UrlEncoder.Encode(body);

// Digest is needed to be passed in the body of the sign operation.
var hash = SHA256.Create();
var digest = hash.ComputeHash(Encoding.UTF8.GetBytes(toBeSigned));
Console.WriteLine(Base64UrlEncoder.Encode(digest));

// API response (using the digest from above)
var signature = "change_this_with_signature_response";

var result = key.VerifyData(Encoding.UTF8.GetBytes(toBeSigned), Encoding.UTF8.GetBytes(signature), HashAlgorithmName.SHA256);
Console.WriteLine(result);

此代码段可以验证签名并返回真实结果。

© www.soinside.com 2019 - 2024. All rights reserved.