c# - 导入 ECC key - CngKey.Import() - 参数不正确

标签 c# jwt x509certificate ecdsa

用途:使用jose-jwt生成ES256签名的JWT

步骤:

1.使用openssl生成私钥证书:

openssl ecparam -name prime256v1 -genkey > privateKey.pem
openssl req -new -key privateKey.pem -x509 -nodes -days 365 -out public.cer

2.代币生成:

var payload = new Dictionary<string, object>()
{
   { "sub", "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3d504f13457d5e525349524e52135e5250" rel="noreferrer noopener nofollow">[email protected]</a>" },
   { "exp", 1300819380   }
};
var certificate = X509Certificate.CreateFromCertFile("public.cer");
byte[] publicKey = certificate.GetPublicKey(); //public key has 65 bytes

//Below step is throwing an error:
var cng = CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob);
var token = JWT.Encode(claims, cng, JwsAlgorithm.ES256);

CngKey.Import() 在尝试生成 所需的 CngKey 时抛出“参数不正确”错误Jose.JWT.Encode 函数。不确定我错过了哪一步。谢谢。

最佳答案

“ECCPUBLICBLOB”格式与证书中的“公钥”字段不同。

ECCPUBLICBLOB 的格式在 another question's answer 中有解释。 ,但这里有一个快速总结:

UINT32 Magic
UINT32 cbKey
<cbKey bytes of public key>

Magic 的值取决于您尝试导入的曲线和算法(https://referencesource.microsoft.com/#system.core/System/Security/Cryptography/BCryptNative.cs,fde0749a0a5f70d8,references 中的一些提示)。

cbKey 是公钥中有多少字节。

公钥字节与您从 GetPublicKey() 获得的内容略有不同。它只是曲线 X 坐标,(对于 NIST P-256)字节 1..33(GetPublicKey() 的第一个字节将为 0x04,这表示有效负载是未压缩,然后是 32 字节的 X 坐标,然后是 32 字节的 Y 坐标)。

IEnumerable<byte> blobBytes = BitConverter.GetBytes(0x31534345);
blobBytes = blobBytes.Append(BitConverter.GetBytes(32));
blobBytes = blobBytes.Append(cert.GetPublicKey().Skip(1).Take(32));

byte[] eccblob = blobBytes.ToArray();

为了简洁起见,使用了 System.Linq 扩展方法。

但是,如果您只需要一个对象实例,cert.GetECDsaPublicKey() 应该为您做正确的事情(每次调用都会返回一个新实例,因此适当管理生命周期)

关于c# - 导入 ECC key - CngKey.Import() - 参数不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42915997/

相关文章:

c# - 当 T 不同时,是否可以获取 List<T> 的项目数?

c# - WP7 : How to Decompress an AES-256 Encrypted Zip File?

asp.net - 如何更改 asp.net core 1 中的 token 响应?

c# - Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware 警告 : 0 : invalid bearer token received

c# - 从本地机器商店中的证书创建 CngKey 以用于 ECDsaCng(CngKey)?

C# SSL/TLS HTTPS 和合法/可信证书错误

go - [golang]是否可以不用证书写TLS服务器?

c# - 与 Xamarin.Forms 一起使用的面向 NoSQL 文档的存储替代方案

c# - 当使用 Directory.Move 时该文件已存在时无法创建该文件

angular - 如何使用spring boot后端使angular app只接收来自局域网的请求?