与 ECDsaCng 算法一起使用的密钥必须具有 ECDsa 算法组
Keys used with the ECDsaCng algorithm must have an algorithm group of ECDsa
我遇到以下问题,找不到解决方案:
在使用 APN(Apple 推送通知)API 时,我实现了令牌化授权。这是 Apple 对其推送通知授权的新方式 api。
Apple 为我提供私钥,我用它来创建 c# CngKey object,然后我用它来签署数据。
CngKey key = CngKey.Import(
Convert.FromBase64String(privateKey),
CngKeyBlobFormat.Pkcs8PrivateBlob);
using (ECDsaCng dsa = new ECDsaCng(key))
{
dsa.HashAlgorithm = CngAlgorithm.Sha256;
var unsignedJwtData =
Url.Base64urlEncode(Encoding.UTF8.GetBytes(header)) + "." + Url.Base64urlEncode(Encoding.UTF8.GetBytes(payload));
var signature =
dsa.SignData(Encoding.UTF8.GetBytes(unsignedJwtData));
return unsignedJwtData + "." + Url.Base64urlEncode(signature);
}
结果是签名令牌,然后我将其用作授权 header,同时使用 API 和发送推送通知。
它在我的开发机器上运行良好,但是当我将它部署到 Windows 服务器时,当这段代码运行时我得到下一个:
System.ArgumentException: Keys used with the ECDsaCng algorithm must have an algorithm group of ECDsa.
Parameter name: key
at System.Security.Cryptography.ECDsaCng..ctor(CngKey key)
at OTTCommon.Encryption.ECDSA.SignES256(String privateKey, String header, String payload, ILog log)
我找不到解决方案,它有 windows 密钥存储或类似的东西....
我该怎么办?
这已在 .NET Framework 4.6.2 中修复,因此最简单的解决方案可能是升级服务器。
适用于 NIST P-256、NIST P-384 和 NIST P-521 的解决方法是更改 blob 导出中的 dwMagic 值。 (它不适用于 Windows 10 通用 ECC,因为 dwMagic 值的对齐方式不同)。
byte[] blob = key.Export(CngKeyBlobFormat.EccPrivateBlob);
key.Dispose();
此 blob 的前 4 个字节映射到 BCRYPT_ECCKEY_BLOB 结构中的 dwMagic
值。
BCRYPT_ECDH_PRIVATE_P256_MAGIC
的值为 0x324B4345
,这是 "ECK2"(椭圆曲线密钥交换 2)的 Little-Endian 表示。 BCRYPT_ECDSA_PRIVATE_P256_MAGIC
的值为 0x32534345
,这是 "ECS2"(椭圆曲线签名 2)的 Little-Endian 表示。
// Change it from Key-exchange (ECDH) to Signing (ECDSA)
blob[1] = 0x53;
key = CngKey.Import(blob, CngKeyBlobFormat.EccPrivateBlob);
现在它看到它是一个 ECDSA 密钥,一切都很开心。
我遇到以下问题,找不到解决方案:
在使用 APN(Apple 推送通知)API 时,我实现了令牌化授权。这是 Apple 对其推送通知授权的新方式 api。
Apple 为我提供私钥,我用它来创建 c# CngKey object,然后我用它来签署数据。
CngKey key = CngKey.Import(
Convert.FromBase64String(privateKey),
CngKeyBlobFormat.Pkcs8PrivateBlob);
using (ECDsaCng dsa = new ECDsaCng(key))
{
dsa.HashAlgorithm = CngAlgorithm.Sha256;
var unsignedJwtData =
Url.Base64urlEncode(Encoding.UTF8.GetBytes(header)) + "." + Url.Base64urlEncode(Encoding.UTF8.GetBytes(payload));
var signature =
dsa.SignData(Encoding.UTF8.GetBytes(unsignedJwtData));
return unsignedJwtData + "." + Url.Base64urlEncode(signature);
}
结果是签名令牌,然后我将其用作授权 header,同时使用 API 和发送推送通知。
它在我的开发机器上运行良好,但是当我将它部署到 Windows 服务器时,当这段代码运行时我得到下一个:
System.ArgumentException: Keys used with the ECDsaCng algorithm must have an algorithm group of ECDsa.
Parameter name: key
at System.Security.Cryptography.ECDsaCng..ctor(CngKey key)
at OTTCommon.Encryption.ECDSA.SignES256(String privateKey, String header, String payload, ILog log)
我找不到解决方案,它有 windows 密钥存储或类似的东西....
我该怎么办?
这已在 .NET Framework 4.6.2 中修复,因此最简单的解决方案可能是升级服务器。
适用于 NIST P-256、NIST P-384 和 NIST P-521 的解决方法是更改 blob 导出中的 dwMagic 值。 (它不适用于 Windows 10 通用 ECC,因为 dwMagic 值的对齐方式不同)。
byte[] blob = key.Export(CngKeyBlobFormat.EccPrivateBlob);
key.Dispose();
此 blob 的前 4 个字节映射到 BCRYPT_ECCKEY_BLOB 结构中的 dwMagic
值。
BCRYPT_ECDH_PRIVATE_P256_MAGIC
的值为 0x324B4345
,这是 "ECK2"(椭圆曲线密钥交换 2)的 Little-Endian 表示。 BCRYPT_ECDSA_PRIVATE_P256_MAGIC
的值为 0x32534345
,这是 "ECS2"(椭圆曲线签名 2)的 Little-Endian 表示。
// Change it from Key-exchange (ECDH) to Signing (ECDSA)
blob[1] = 0x53;
key = CngKey.Import(blob, CngKeyBlobFormat.EccPrivateBlob);
现在它看到它是一个 ECDSA 密钥,一切都很开心。