我的本地计算机(dotnet 8.0)上有这个代码片段,运行良好。
using System.Security.Cryptography;
using (ECDsa ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP256))
{
string input = "some base64 encoded data";
byte[] data_bytes = Convert.FromBase64String(input);
byte[] hash = SHA256.Create().ComputeHash(data_bytes);
byte[] publicKeyBytes = ecdsa.ExportSubjectPublicKeyInfo();
Console.WriteLine($"Public Key:\n{Convert.ToBase64String(publicKeyBytes)}\n");
// Sign the hash using the Rfc3279DerSequence format
byte[] signature_der = ecdsa.SignHash(hash, DSASignatureFormat.Rfc3279DerSequence);
bool isValid_der = ecdsa.VerifyHash(hash, signature_der, DSASignatureFormat.Rfc3279DerSequence);
Console.WriteLine($"Signature valid: {isValid_der}\n");
string signature_b64_der = Convert.ToBase64String(signature_der);
Console.WriteLine($"DER Signature:\n{signature_b64_der}\n");
// Sign the hash using the IeeeP1363FixedFieldConcatenation format
byte[] signature_ieee = ecdsa.SignHash(hash, DSASignatureFormat.IeeeP1363FixedFieldConcatenation);
bool isValid_ieee = ecdsa.VerifyHash(hash, signature_ieee, DSASignatureFormat.IeeeP1363FixedFieldConcatenation);
Console.WriteLine($"Signature valid: {isValid_ieee}\n");
string signature_b64_ieee = Convert.ToBase64String(signature_ieee);
Console.WriteLine($"IEEE Signature:\n{signature_b64_ieee}\n");
}
我想实现相同的逻辑,但这次我想使用 Azure Key Vault REST API 来 sign 和 verify 相同类型的数据。我的目标是采用这种方法,这样我就可以定期轮换密钥。
Azure Key Vault 返回的签名似乎仅以 IEEE P1363 格式返回,我没有找到返回 RFC 3279 DER 序列格式的方法。
我的问题:有没有办法从 Azure Key Vault 获取不同格式的签名,并且当然能够验证该签名?
我尝试使用 CryptographyClient.SignAsync,但它再次仅返回 IEEE P1363 格式,我也想要其他格式(如果可能)。
Azure Key Vault 的加密操作(如
Sign
和 SignAsync
)确实使用 IEEE P1363 格式进行 ECDSA 签名,并且不提供输出 RFC 3279 DER 序列格式的选项。但是,如果需要,您可以手动将 IEEE P1363 格式签名转换为 RFC 3279 DER 序列格式。
这是实现转换的方法:
了解 IEEE P1363 和 DER 格式
r
和 s
值,无需任何额外的元数据。r
和 s
封装在一个序列中。从 IEEE P1363 到 DER 的转换
该过程涉及:
r
和 s
。r
和 s
并创建序列。这是执行此转换的代码:
using System;
using System.Formats.Asn1;
using System.Security.Cryptography;
public static byte[] ConvertIeeeP1363ToDer(byte[] ieeeSignature)
{
if (ieeeSignature.Length % 2 != 0)
{
throw new ArgumentException("Invalid IEEE P1363 signature length");
}
int halfLength = ieeeSignature.Length / 2;
byte[] r = new byte[halfLength];
byte[] s = new byte[halfLength];
Array.Copy(ieeeSignature, 0, r, 0, halfLength);
Array.Copy(ieeeSignature, halfLength, s, 0, halfLength);
var writer = new AsnWriter(AsnEncodingRules.DER);
writer.PushSequence();
writer.WriteInteger(r);
writer.WriteInteger(s);
writer.PopSequence();
return writer.Encode();
}
在代码中使用转换
ConvertIeeeP1363ToDer
函数将其转换为 DER。ECDsa.VerifyHash
在本地验证 DER 格式的签名。以下是如何将此转换与代码的其余部分集成:
using System;
using System.Security.Cryptography;
byte[] ieeeSignature = await cryptographyClient.SignAsync(SignatureAlgorithm.ES256, hash);
byte[] derSignature = ConvertIeeeP1363ToDer(ieeeSignature);
// Now verify with DER format if needed
bool isValidDer = ecdsa.VerifyHash(hash, derSignature, DSASignatureFormat.Rfc3279DerSequence);
Console.WriteLine($"Signature valid in DER format: {isValidDer}");
r
和 s
组件,并以 DER 序列格式写入。ECDsa.VerifyHash
和 DSASignatureFormat.Rfc3279DerSequence
选项在本地验证它。限制和注意事项
nistP256
,其中 r
和 s
各为 32 字节。对于其他曲线,相应地调整字节长度。这应该使您能够使用 Azure Key Vault 进行签名,并在需要时使用 DER 格式签名进行验证。