我在 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);
我总是得到错误的结果。
以下是基于@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);
此代码段可以验证签名并返回真实结果。