在 .NET 中加载椭圆曲线 (EC) 密钥

本文将讨论在.NET 中解析和加载EC 密钥的不同方式。在本文中,您将了解 EC 密钥的构成,然后了解如何以四种不同的方式使用这些知识ECDsa在 .NET 中加载或创建对象。到本文结束时,您应该能够加载 EC 密钥,无论格式如何。

本文针对 .NET Core 3.1 及更高版本。

椭圆曲线 (EC) 密钥的参数

加载 EC 密钥时,您将需要了解三件事:

1.私钥(可选)2.公钥3.您需要使用的曲线

私钥d是一个随机整数,其长度取决于您使用的曲线。如果你有私钥,你就可以对数据进行签名。

公钥是椭圆曲线上的一个点,使用坐标x&y。因此,公钥特定于该曲线,并使用私钥乘以曲线上的生成点G生成。使用公钥,您将能够验证签名。

这表明您需要了解正在使用的椭圆曲线(例如,NIST 的 P-256[1]或secp256k1[2])才能使用椭圆曲线加密 (ECC)。如果不知道曲线,您将不知道私钥应该有多长、提供的安全级别或公钥是否有效(如果它们是曲线上的点)。

如果您想了解有关椭圆曲线密码学工作原理的更多信息,我发现开发人员实用密码学[3]是一本有用的读物。

.NET 的ECDsa对象

.NET 对 ECDSA 的抽象是ECDsaSystem.Security.Cryptography. 这继承AsymmetricAlgorithm并遵循RSA您之前可能使用过的类的类似模式。 ECDsa是一个抽象类,具有使用不同实现的各种平台(例如,Windows 上的 CNG 和 Linux 上的 OpenSSL)。

此类的主要用途是调用SignDataVerifyData方法。否则,您可能会将其传递到SecurityKey 实现[4]或 SignedXml。

本文的其余部分将重点介绍如何创建ECDsa实现。

使用ECDsa和命名曲线生成 EC 密钥

创建新 EC 密钥的最简单方法是使用 .NETCreate上的方法让 .NET 为您完成ECDsa。这将在您选择的曲线上创建一个私钥。您通常会使用已知的命名曲线,例如 NIST 的 P-256,又名 secp256r1。您可以在ECCurve.NamedCurve课程中找到 .NET 支持的开箱即用曲线。

ECDsa key = ECDsa.Create(ECCurve.NamedCurves.nistP256);

这种方法非常适合在测试期间即时生成密钥,但是一旦对象被处置,您就会丢失密钥。幸运的是,您可以使用各种导出方法ECDsa;否则,您可以使用该ExportParameters方法直接访问 EC 参数。这些导出方法使您可以访问ECParameters包含关键点曲线、D 和 Q ( x & y ) 点的对象,您将在接下来的操作中看到这些点。

创建ECDSA使用为ECParameters

假设您已经收到曲线的原始点,并且您需要以这种方式加载密钥。这在使用 JSON Web Keys (JWK) 和OpenID Connect[5]时很常见。

这是来自 RFC 7517 的 JWK 示例:

{"kty": "EC","crv": "P-256","x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU","y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0","kid": "my EC key"
}

要加载密钥,您需要知道密钥使用什么曲线以及公钥参数(x和y坐标)。也可以使用d参数将私钥包含在 JWK 中;然而,这种情况很少见。

您可以再次使用ECDsaCreate方法加载这些坐标,但这次您将传入一些ECParameters.

// parse curve from JOSE format
// https://www.iana.org/assignments/jose/jose.xhtml#web-key-elliptic-curve
var curve = crv switch
{"P-256" => ECCurve.NamedCurves.nistP256,"P-384" => ECCurve.NamedCurves.nistP384,"P-521" => ECCurve.NamedCurves.nistP521,_ => throw new NotSupportedException()
};ECDsa key = ECDsa.Create(new ECParameters
{Curve = curve,D = Base64UrlEncoder.DecodeBytes(d), // optionalQ = new ECPoint{X = Base64UrlEncoder.DecodeBytes(x),Y = Base64UrlEncoder.DecodeBytes(y)}
});

在这里,您正在解析 JOSE 名称中的曲线,并使用 中找到的编码器对其他参数进行 base64url 解码Microsoft.IdentityModel.Tokens

此解析特定于 JWK 使用的格式,但它演示了如何在知道其参数的情况下加载 EC 密钥。

有一种Validate方法ECParameters可以检查关键和坐标大小并检查曲线是否有效。但是,Createon的方法ECDsa会为您调用它。

如果您确实有 JWK 并打算使用它来验证 JWT,我建议将 JWK 直接传递到构造函数中Microsoft.IdentityModel.Tokens.JsonWebKey并跳过我在上面演示的手动解析。

从X509Certificate2加载ECDsa

从 an 加载 EC 密钥X509Certificate2是简单使用GetECDsaPrivateKeyGetECDsaPublicKey方法的一种情况。

ECDsa key = cert.HasPrivateKey ? cert.GetECDsaPrivateKey() : cert.GetECDsaPublicKey();

为了首先加载X509Certificate2,您可以从 PEM 文件加载它[6]

X509Certificate2.PrivateKey与GetRSAPrivateKey和GetECDsaPrivateKey

过去,您可能在 上使用了PrivateKeyPublicKey属性X509Certificate2。但是,如果您尝试在包含 EC 密钥的证书上使用这些属性,您将获得 null forPrivateKey和以下异常PublicKey

System.NotSupportedException: 不支持证书密钥算法。在 System.Security.Cryptography.X509Certificates.PublicKey.get_Key()

要使用来自 X.509 的 EC 密钥,您需要使用GetECDsaPrivateKeyGetECDsaPublicKey方法。

从 .NET 6 开始,PrivateKeyPublicKey属性被标记为过时。因此,您必须使用RSAECDsa特定方法来全面加载密钥。

从十六进制字符串加载ECDsa

有时,您会看到 EC 密钥作为十六进制字符串共享。这在加密社区中很常见,我的意思是密码学和加密货币。我不能说它在密码学中是否有很大用处。这些键看起来像这样:

Private: c711e5080f2b58260fe19741a7913e8301c1128ec8e80b8009406e5047e6e1ef
Public: 04e33993f0210a4973a94c26667007d1b56fe886e8b3c2afdd66aa9e4937478ad20acfbdc666e3cec3510ce85d40365fc2045e5adb7e675198cf57c6638efa1bdb

这些键起初可能看起来有点奇怪,但它们实际上映射回您已经使用的参数。私钥只是d参数的十六进制表示,公钥是连接在一起的x &y坐标(第一个字节是标签)。

因此,您可以再次使用ECParameters来创建您的ECDsa对象:

public static ECDsa LoadFromHex()
{var privateKeyBytes = FromHexString("c711e5080f2b58260fe19741a7913e8301c1128ec8e80b8009406e5047e6e1ef");var publicKeyBytes = FromHexString("04e33993f0210a4973a94c26667007d1b56fe886e8b3c2afdd66aa9e4937478ad20acfbdc666e3cec3510ce85d40365fc2045e5adb7e675198cf57c6638efa1bdb");return ECDsa.Create(new ECParameters{Curve = ECCurve.NamedCurves.nistP256, // you'd need to know the curve before handD = privateKeyBytes,Q = new ECPoint{X = publicKeyBytes.Skip(1).Take(32).ToArray(),Y = publicKeyBytes.Skip(33).ToArray()}});
}private static byte[] FromHexString(string hex) {var numberChars = hex.Length;var hexAsBytes = new byte[numberChars / 2];for (var i = 0; i < numberChars; i += 2)hexAsBytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);return hexAsBytes;
}

源代码

您可以在我的GitHub 示例存储库中[7]找到演示上述方法的可执行代码。此代码是多目标 .NET Core 3.1 及以上版本,可在 Windows 和 Linux 上运行。

查看原文:https://www.scottbrady91.com/c-sharp/ecdsa-key-loading

References

[1] NIST 的 P-256: https://www.scottbrady91.com/C-Sharp/JWT-Signing-using-ECDSA-in-dotnet-Core
[2] secp256k1: https://www.scottbrady91.com/C-Sharp/Supporting-Custom-JWT-Signing-Algorithms-in-dotnet-Core
[3] 开发人员实用密码学: https://cryptobook.nakov.com/asymmetric-key-ciphers/elliptic-curve-cryptography-ecc
[4] SecurityKey 实现: https://www.scottbrady91.com/C-Sharp/JWT-Signing-using-ECDSA-in-dotnet-Core
[5] OpenID Connect: https://www.scottbrady91.com/OpenID-Connect/OpenID-Connect-Overview
[6] 从 PEM 文件加载它: https://www.scottbrady91.com/C-Sharp/PEM-Loading-in-dotnet-core-and-dotnet
[7] GitHub 示例存储库中: https://github.com/scottbrady91/Blog-Example-Classes/tree/master/EcdsaKeyLoading

在 .NET 中加载椭圆曲线 (EC) 密钥相关推荐

  1. 在C++中加载TorchScript模型

    在C++中加载TorchScript模型 本教程已更新为可与PyTorch 1.2一起使用 顾名思义,PyTorch的主要接口是Python编程语言.尽管Python是合适于许多需要动态性和易于迭代的 ...

  2. xBIM 实战01 在浏览器中加载IFC模型文件

    系列目录    [已更新最新开发文章,点击查看详细]  一.创建Web项目 打开VS,新建Web项目,选择 .NET Framework 4.5  选择一个空的项目 新建完成后,项目结构如下: 二.添 ...

  3. Spring中加载xml配置文件的六种方式

    Spring中加载xml配置文件的六种方式 博客分类: Spring&EJB XMLSpringWebBeanBlog  因为目前正在从事一个项目,项目中一个需求就是所有的功能都是插件的形式装 ...

  4. 如何在Author中加载SDE栅格图层?

    如何在Author中加载SDE栅格图层? 版本: ArcIMS  9.1 在Author中加载SDE栅格图层,并保存AXL文件. 过程描述 1.使用ArcIMS Author工具正常的连接ArcSDE ...

  5. 如何找出R中加载的软件包版本?

    本文翻译自:How to find out which package version is loaded in R? I am in a process of figuring out how to ...

  6. pyharm虚拟环境_手把手教你如何在Pycharm中加载和使用虚拟环境

    /1 前言/ 上次小编给大家介绍了Python虚拟环境及其使用和操作教程,没来得及上车的小伙伴,可以戳这个文章进行阅览.这篇文章基于虚拟环境的搭建,也相对比较基础,主要是介绍如何在Pycharm中加载 ...

  7. Activity中加载器的总结

    继续总结加载器 加载器可以支持在Activity或片段中异步加载数据,加载器具有以下特征: 可用于每个Activity和Fragment: 支持异步加载数据: 监控其数据源并在内容变化时传递新结果: ...

  8. webpack 中的加载器简介||webpack 中加载器的基本使用——1. 打包处理 css 文件 2. 打包处理 less 文件 3.打包处理 scss 文件

    webpack 中的加载器 1. 通过 loader 打包非 js 模块 在实际开发过程中,webpack 默认只能打包处理以 .js 后缀名结尾的模块,其他非 .js 后缀名结尾的模块, webpa ...

  9. 通过超图在网页中加载3dmax模型

    接此: https://blog.csdn.net/bcbobo21cn/article/details/116806866 在场景中加载了3dmax模型后,保存场景: 场景节点下面出来一个场景: 保 ...

最新文章

  1. 不能成为专业软件测试人员的10大理由
  2. 参会邀请 | “新时代与新范式:新兴交叉学科的研究议程与发展路径”——第三届全国计算社会科学高端论坛...
  3. linux ifconfig命令配置ip地址
  4. python回顾(四)——面向对象
  5. 2.3.3 Softmax回归介绍
  6. CS这么难申,小哥哥你怎么拿到全美最高额度奖学金的?
  7. Vista新特征(Features)(英文)
  8. 自制H3C交换机CONSOLE线
  9. mui switch 实现方案 让你的html 设计更贴近原生
  10. 学英语---(2)脱口而出100句经典英语口语
  11. 数据库服务的安装,启动,关闭
  12. 配置实体框架DbContext的可扩展方案
  13. java jlabel 字体大小_java – 如何在调整大小时更改JLabel字体大小以填充JPanel可用空间?...
  14. numpy教程:numpy基本数据类型及多维数组元素存取
  15. Java JVM调优
  16. Ubuntu22.04运行网易云音乐错误
  17. 【pyqt5学习】——pyqt5中.qrc资源文件的创建与编写
  18. SetWindowsHookEx 全局钩子
  19. 使用导入 Excel 的方式批量修改文件名称及文件扩展名
  20. 资源池、虚拟机、集群的关系

热门文章

  1. 转:IOS开发之----Xcode非ARC项目中设置部分文件ARC支持
  2. 旅游社交网站 游范儿
  3. X-Scan描述及简单教程
  4. Exchange中的数据库文件
  5. 使用网页对话框来显示图片 window.open()
  6. opencv-原图基础上添加指定颜色
  7. Discuz X3.2源码解析 discuz_application类(转自百度)
  8. [矩形并-扫描线-线段树]Picture
  9. 浅谈Java多线程同步机制之同步块(方法)——synchronized
  10. php扩展开发1--添加函数