微软 CNG |如何将 PEM 编码的 ECDSA 私钥导入 MS Key Storage Provider

2023-11-21

我知道 MS CNG 私人有这种格式 - BCRYPT_ECCKEY_BLOB BYTE X[cbKey] // Big-endian. BYTE Y[cbKey] // Big-endian. BYTE d[cbKey] // Big-endian.

因此尝试导入以下关键字节 -

byte[] ec256PrivKB =
{
//Magic + CBLength
0x45, 0x43, 0x53, 0x31, 0x20, 0x00, 0x00, 0x00,
//X
0xA7, 0xFB, 0xCD, 0x4D, 0x7E, 0x43, 0x6F, 0x22, 0xBD, 0x74, 0xFA, 0x1F, 0xD7, 0x10, 0xDB, 0x8C, 0xF8, 0x29, 0xC1, 0xEC, 0x5E, 0x15, 0x1E, 0xE2, 0x84, 0x56, 0x3E, 0x54, 0x6E, 0x1D, 0x5C, 0xF6, 
//Y
0x6B, 0x42, 0x21, 0xD1, 0x92, 0xEB, 0x69, 0x66, 0x56, 0xD6, 0xEC, 0x4D, 0x21, 0xB7, 0xDB, 0x3C, 0x94, 0x56, 0x8D, 0x87, 0xEB, 0x1C, 0x11, 0x0F, 0x03, 0x80, 0xF6, 0x10, 0x70, 0x73, 0x7D, 0x1D, 
//D
0x5E, 0xF0, 0x2A, 0x1B, 0x34, 0xE9, 0x2B, 0x96, 0xA4, 0xAE, 0x05, 0x1D, 0x33, 0x53, 0x36, 0x39, 0x7B, 0x1F, 0xF5, 0x24, 0xA4, 0xD6, 0xBD, 0x12, 0x07, 0x3F, 0x43, 0x30, 0x70, 0x32, 0x4E, 0x5D
};

现在正在通话中

ECDsaCng eCDsa = new ECDsaCng( CngKey.Import(ec256PrivKB, CngKeyBlobFormat.EccPrivateBlob,
                    CngProvider.MicrosoftSoftwareKeyStorageProvider));

它给System.Security.Cryptography.CryptographicException: 'The requested operation is not supported.我不明白为什么它会给出这个例外?

另外,如何将 Base64 编码的 ECDSA 私钥导入 MS 密钥存储提供程序,即假设我有以下 EC 私钥 -

-----BEGIN EC PRIVATE KEY-----
MHcCAQEEICWeuFHssg5i2vJlyMHPUb+DJnylxfbkR8KJPXfYw5ikoAoGCCqGSM49
AwEHoUQDQgAE7A4wVMLQ+orOZYcFv6mLNBbAWfffPwTTw4iroyQDcytYWT+frzl3
RiFXqC1niHgduYtGBZIbwq/48ooyL9HbkA==
-----END EC PRIVATE KEY-----

现在我如何将其导入 CNG 提供商?

Edit- 还有什么方法可以回报这个过程,即 我知道如何转换OpenSSL(PEM FORMAT) to MS Format(RAW format)但如何做相反的意思 如何转换MS将 ECDSA 密钥格式化为OpenSSLPEM 中的 EC 密钥。


您的密钥 blob 以 BCRYPT_ECDSA_ 开头PUBLIC_P256_MAGIC,但你想要 BCRYPT_ECDSA_PRIVATE_P256_MAGIC(将0x31更改为0x32)。

由此我们可以假设您知道如何进行转换,但由于标题询问如何更一般地进行转换,我将继续。C# 从文本文件中的公钥获取 CngKey 对象对公钥有一个简单的(如果是黑客的)答案。私钥有所不同,但大多很简单。

如果我们从问题中获取 PEM 密钥,我们可以移除“PEM 盔甲”以获得 Base-64 blob。将 base-64 blob 转换为十六进制,我们得到

30 77 02 01 01 04 20 25 9E B8 51 EC B2 0E 62 DA 
F2 65 C8 C1 CF 51 BF 83 26 7C A5 C5 F6 E4 47 C2 
89 3D 77 D8 C3 98 A4 A0 0A 06 08 2A 86 48 CE 3D 
03 01 07 A1 44 03 42 00 04 EC 0E 30 54 C2 D0 FA 
8A CE 65 87 05 BF A9 8B 34 16 C0 59 F7 DF 3F 04 
D3 C3 88 AB A3 24 03 73 2B 58 59 3F 9F AF 39 77 
46 21 57 A8 2D 67 88 78 1D B9 8B 46 05 92 1B C2 
AF F8 F2 8A 32 2F D1 DB 90

如果我们然后打开https://www.secg.org/sec1-v2.pdfC.4节我们看到

ECPrivateKey ::= SEQUENCE {
  version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
  privateKey OCTET STRING,
  parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL,
  publicKey [1] BIT STRING OPTIONAL
}

通过 ASN.1 (ITU-T X.680) 和 BER/DER (ITU-T X.690)规格,我们可以混合该十六进制转储和该结构:

// (constructed) SEQUENCE, 119 content bytes
30 77
   // INTEGER, 1 content byte, value 0x01.
   02 01 01
   // OCTET STRING (byte[]), 32 bytes, value 25 9E ... 98 A4
   04 20
      25 9E B8 51 EC B2 0E 62 DA F2 65 C8 C1 CF 51 BF 
      83 26 7C A5 C5 F6 E4 47 C2 89 3D 77 D8 C3 98 A4
   // (constructed) CONTEXT-SPECIFIC 0, 10 content bytes
   A0 0A
      // OBJECT IDENTIFIER, 8 content bytes, 1.2.840.10045.3.1.7
      06 08 2A 86 48 CE 3D 03 01 07
   // (constructed) CONTEXT-SPECIFIC 1, 68 content bytes
   A1 44
      // BIT STRING, 66 content bytes, 0 unused bits, value 04 EC .. DB 90
      03 42
         00
         04 EC 0E 30 54 C2 D0 FA 8A CE 65 87 05 BF A9 8B 
         34 16 C0 59 F7 DF 3F 04 D3 C3 88 AB A3 24 03 73 
         2B 58 59 3F 9F AF 39 77 46 21 57 A8 2D 67 88 78 
         1D B9 8B 46 05 92 1B C2 AF F8 F2 8A 32 2F D1 DB 
         90

Doing a 搜索 1.2.840.10045.3.1.7表明它(不出所料)是 secp256r1 / NIST P-256 椭圆曲线。

BIT STRING 的内容以04,表示是未压缩的EC点,剩下的前半部分是X坐标,后半部分是Y坐标。很好,这与私钥的八位字节字符串的宽度一致,这意味着该结构是有效的。

您会注意到,ASN.1 结构表示曲线标识符和公钥在技术上都是可选的。实际上,它们被写下来,这很好,因为我们将依赖它。

将 EC 私钥 blob 转换为 CNG blob

// structure opening up to the private key (D) value.
private static readonly byte[] s_secp256R1Prefix =
    { 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20 };

// After D through the 0x04 identifying the public key is uncompressed
private static readonly byte[] s_secp256R1Infix =
{
    0xA0, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE,
    0x3D, 0x03, 0x01, 0x07, 0xA1, 0x44, 0x03, 0x42,
    0x00, 0x04
};

private static readonly byte[] s_secp256R1PrivateCngPrefix =
    { 0x45, 0x43, 0x53, 0x32, 0x20, 0x00, 0x00, 0x00 };

private static CngKey DecodeP256ECPrivateKeyBase64(string base64)
{
    byte[] derBlob = Convert.FromBase64String(base64);

    if (derBlob.Length == 121 &&
        derBlob.Take(s_secp256R1Prefix.Length).SequenceEqual(s_secp256R1Prefix) &&
        derBlob.Skip(0x20 + s_secp256R1Prefix.Length).Take(s_secp256R1Infix.Length).
            SequenceEqual(s_secp256R1Infix))
    {
        byte[] cngBlob = new byte[2 * sizeof(uint) + 3 * 0x20];
        int offset = 0;

        // Header (BCRYPT_ECDSA_PRIVATE_P256_MAGIC and 0x00000020)
        Buffer.BlockCopy(
            s_secp256R1PrivateCngPrefix,
            0,
            cngBlob,
            offset,
            s_secp256R1PrivateCngPrefix.Length);

        offset += s_secp256R1PrivateCngPrefix.Length;

        // X and Y
        Buffer.BlockCopy(
            derBlob,
            s_secp256R1Prefix.Length + 0x20 + s_secp256R1Infix.Length,
            cngBlob,
            offset,
            2 * 0x20);

        offset += 2 * 0x20;

        Buffer.BlockCopy(
            derBlob,
            s_secp256R1Prefix.Length,
            cngBlob,
            offset,
            0x20);

        offset += 0x20;
        Debug.Assert(offset == cngBlob.Length);

        return CngKey.Import(cngBlob, CngKeyBlobFormat.EccPrivateBlob);
    }

    throw new InvalidOperationException();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

微软 CNG |如何将 PEM 编码的 ECDSA 私钥导入 MS Key Storage Provider 的相关文章

  • 如何解决“无法加载PEM客户端证书,OpenSSL错误:02001003:系统库:fopen:没有这样的进程”错误?

    如果这个问题很愚蠢 请原谅 但我是这个领域的新手 我需要通过 SSL 从 Drupal 7 站点连接到服务 我有一个扩展名为 p12 的文件及其密码 另外 我使用 PHP 7 1 1 和 Windows 7 64x 我使用以下命令将 p12
  • OpenSSL DH 密钥太小错误

    我正在尝试使用简单的 PERL 脚本连接到封闭的服务器 空调 usr bin perl use 5 10 1 use warnings use strict use IO Socket SSL use IO Socket SSL qw de
  • 为什么AES java解密返回额外的字符?

    请原谅我英语不好 我使用 mcrypt 我从这里得到它用于 php 和 java 的 MCrypt https snipt net raw ee573b6957b7416f28aa560ead71c3a2 nice 在我的android应用
  • 在 Swift 中使用 CommonCrypto 解密时出现问题

    我在一家Swift only加密 解密Extension for String and NSData 并且 crypt 部分的工作基于 Zaph 在链接问题中提供的答案 在 Swift 中使用 CCCrypt CommonCrypt 时出现
  • 这个巨大的正则表达式是如何工作的?

    我最近在我的一个目录中的一个名为的文件中找到了下面的代码doc php 文件功能或链接到文件管理器 做得非常好 基本上 它列出了当前目录中的所有文件 并且允许您更改目录 它可以访问我的所有文件 添加 重命名 信息 删除 我不记得安装过它 我
  • 使用openssl解密用java加密的aes-gcm

    我有以下 Java 代码 public static void deriveKeyAndIV String password throws Exception SecureRandom random new SecureRandom if
  • 使用ssl和socket的python客户端身份验证

    我有一个 python 服务器 需要客户端使用证书进行身份验证 我如何制作一个客户端脚本 使用客户端证书由 python 中的服务器使用 ssl 和套接字模块进行身份验证 有没有仅使用套接字和 ssl 而不扭曲的示例 from OpenSS
  • 无法将 /root/.rnd 加载到 RNG 中

    我想使用 Windows Open SSL 生成服务器证书 当我运行此命令行时 出现此错误 我应该怎么办 Command openssl req new x509 days 3650 key ca key out ca crt Error
  • iOS SecItemCopyMatching RSA 公钥格式?

    我正在尝试从已生成的密钥对 两个SecKeyRefs 以便通过线路发送 我所需要的只是一个简单的 modulus exponent 对 它应该正好占用 131 个字节 模数为 128 指数为 3 但是 当我获取关键信息时NSData对象 我
  • 在提交到 Mac App Store 的应用程序中调用 openssl 是否可以接受?

    我有点不清楚调用提交到 App Store 的应用程序之外的进程的规则是什么 我读到 如果您想使用 Cocoa 和 OSX 库之外的其他库 框架 您必须将其包含在您的应用程序中 例如 如果使用 QT Python 或 Ruby 编写应用程序
  • TweetNaCl.js 最小公钥签名示例

    我试图了解如何基于位于的演示来实现一个最小的基本公钥签名示例here https tweetnacl js org sign 使用纯javascript 我的研究还没有产生一个简单的 javascript 示例 我可以用它来理解其内部工作原
  • OpenSSL HMAC 函数中的意外复杂性

    SSL 文档分析 这个问题与 OpenSSL 中 HMAC 例程的使用有关 由于 Openssl 文档在某些领域有点薄弱 分析表明使用 unsigned char HMAC const EVP MD evp md const void ke
  • 在 python 2.7 中更新 openssl

    想知道是否有人可以解释 openssl 在 python2 7 中如何工作 我不确定 python 是否有自己的 openssl 或者从本地机器 env 中获取它 让我解释 如果我在Python中这样做 gt gt gt import ss
  • 没有 ssl 的 Web 加密 API

    我编写了一个用于安全消息传输的小网络应用程序 以了解有关加密的更多信息 并想向我的朋友展示它并让他们玩一下 所以我将它托管在我的小服务器上 并惊讶地发现 Web Crypto API 我竭尽全力开始工作 因为它的错误消息不是很具体 需要 S
  • 如何从密钥对的现有公钥创建证书签名请求 (CSR)(假设私钥位于其他地方的安全位置)?

    我正在使用 OpenSSL openSSL的所有参考文献都集中在以下两个创建CSR的命令 一个要求您输入一个已经存在的私钥 并派生公钥 第二个将创建一个新的密钥对 我想使用我的公钥而不是创建新的 创建 CSR 和私钥 openssl req
  • 160 位 SHA1 哈希值的前 32 位是否可以替代 CRC32 哈希值?

    我正在开发一个 NET 3 5 项目 我需要一个 32 位哈希值 NET 加密类中似乎没有任何方法返回 32 位哈希 MD5 是 128 位 SHA1 是 160 位等 我实现了一个 CRC32 类 但我发现现有的 SHA1 和 MD5 哈
  • 将 RSA 密钥从 BigIntegers 转换为SubjectPublicKeyInfo 形式

    WARNING 最初的问题是关于 PKCS 1 编码密钥 而问题中的实际示例需要SubjectPublicKeyInfo X 509 编码密钥 我目前正致力于在 java 中从头开始实现 RSA 算法 特别是密钥生成方面 现在我的代码可以给
  • 在 .NET 中加载 ECC 私钥

    我有一个 ECC 私有密钥和一个包含公钥的证书文件 我可以获取 PEM 或 DER 格式的文件 我可以将证书读入X509Certificate用这个代码 var certbytes File ReadAllBytes certificate
  • 如何读取密钥文件以与 HMAC_Init_ex() 一起使用

    我使用 openssl 生成了 RSA 私钥 我需要使用纯 C 语言中的 OpenSSL 库的 HMAC 函数来对数据进行哈希 签名 但我不确定如何从该文件中正确提取私钥数据 据我所知 该文件是 B64 编码的 因此我将其取消编码并将其存储
  • xampp openssl 调用 openssl_pkey_new() 时出错;

    所以我试图让 openssl 在我的 Windows 安装的 xampp 1 7 3 上工作 它是用 OpenSSL 0 9 8l 构建的 这只是我第二次在 amp 安装上安装 openssl 但第一次进展顺利 这是在同一台机器上的 wam

随机推荐

  • Git 与 SVN 需要多少空间?

    我们目前使用 Subversion 作为我们的源代码存储库 我们正处于转换为 Git 的规划阶段 我们的 Subversion 存储库目前为 19Gb 在磁盘空间要求方面 Git 存储库与 Subversion 相比如何 我的 19Gb s
  • Docker(Spring Boot 或 Thorntail)和 Keycloak

    我在 docker 容器中运行 Spring Boot 和 Keycloak 时遇到问题 我从 Keycloak 开始 将 mysql 作为在 docker 中运行的数据库 services mysql image mysql 5 7 co
  • 如何访问名称中带有点的 python argparse 参数

    Python 的 argparse 允许我定义名称中包含点的参数名称 但我怎样才能访问这些呢 import argparse parser argparse ArgumentParser parser add argument inputf
  • CSS 最小化器?

    您是否知道在线 CSS 压缩器可以帮助删除冗余 低效的 CSS 声明并用更优化的 CSS 替换它 意思是 我知道存在很多 压缩器 它们只是删除选项卡 删除注释等 但我正在寻找的是足够聪明的东西来知道 border top 1px solid
  • 使 EditText 仅显示小数点后两位

    我想在编辑文本中仅显示两位小数 ofc 我想在编辑文本中显示货币 但将其值限制为小数点后两位 我见过一些使用正则表达式的解决方案 但我不想这样做 有人告诉我 java 支持一些可以做到这一点的内部库函数 任何人都可以给我提示或给我一些有效的
  • 将文本区域接收的数据输出回文本区域时,如何正确清理从文本区域接收的数据?

    用户将在文本区域中输入文本 然后将其直接插入到 mySQL 数据库中 我在上面使用了trim htmlentities mysql real escape string 并且启用了魔术引号 将数据输出回文本区域时应该如何清理它 感谢您的帮助
  • .NET Core 2.0 与 MySQL:指定的键太长;最大密钥长度为 3072 字节

    我是一名 PHP MySQL 开发人员 正在尝试转向其他技术 例如 NET Core 我不确定我是否喜欢从 MySQL 切换到 SQL Server 由于许可 的想法 因此我一直在尝试让 NET Core 与 MySQL 很好地配合 我已经
  • Angular 2 每次按键时都会更改事件

    仅在输入焦点更改后才会调用更改事件 我怎样才能让事件在每次按键时触发
  • d3 地图上的线不形成曲线

    我使用 d3 js 创建了一个地图 我想在两个位置之间显示一条曲线 我能够显示一条线 但有时它不能形成完美的曲线 对于某些线路 线路会在地图后面 穿过反子午线 弯曲到达目的地 这是演示该问题的代码笔 https codepen io pee
  • 多个视图 OnTouch 事件

    我们正在开发一个应用程序 需要同时从多个视图捕获 MotionEvent 当我们尝试这样做时 Android 只会将事件分派到第一个触摸的视图 并且当同时触摸另一个视图时 它只会在第一个视图上为我们提供 ACTION POINTER DOW
  • 如何制作一个出色的 R 可重现示例

    这个问题的答案是社区努力 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 当与同事讨论性能 教学 发送错误报告或在邮件列表和 Stack Overflow 上搜索指导时 可重现的例子经常被问到并且总是有帮助 创建优秀示例的技巧是什么
  • WatchKit WKInterfaceLabel 无法更改字体

    我正在尝试更改标签字体 但是我在属性检查器中设置的每种字体都与系统字体不同 不要更改任何内容 模拟器或故事板都不会更改 我什至尝试使用属性字符串以编程方式设置字体 出现相同的系统字体 感谢您的帮助 目前您无法使用 WatchKit 中包含的
  • 如何获取 UIElement 的父级?

    好的 我知道FrameworkElement 它是一个直接子类UIElement has a Parent财产 但是Panel对象有类型的子对象UIElement not FrameworkElement The Children属性是类型
  • npm 错误! 405 不允许的方法:express@latest

    此处发布的几个 405 相关问题中 没有一个适用于我的问题 以下是我从台式电脑上的 Windows 7 发出的命令 npm install express 这是错误消息 npm ERR code E405 npm ERR 405 Metho
  • Discord.js MessageEmbed fields.flat 不是函数

    我正在使用 JavaScript 和 Discord js 制作一个 Discord 机器人 在那里 我想将 RichEmbed MessageEmbed 我不知道它是如何调用的 发送到通道 但它没有发送嵌入 而是在discord js 中
  • 模板化上下文中的显式析构函数

    我想明确地销毁一个vector在模板化的上下文中 以下内容对我有用 GNU C 4 3 4 4 和 Clang 1 1 template
  • Visual Studio 2015 中的 Qt 项目:“无法解析的外部符号 wWinMain”

    整个错误输出是 LNK2019 unresolved external symbol wWinMain referenced in function int cdecl scrt common main seh void scrt comm
  • 对于“不”来说,什么更“Pythonic”[重复]

    这个问题在这里已经有答案了 两种方式我都见过 但哪种方式更Pythonic a 1 2 3 version 1 if not 4 in a print is the not more pythonic version 2 if 4 not
  • PHPUnit 断言相同的 HTML 结构,无论空格如何

    我有一个命令行脚本 可以生成一些 HTML 我正在尝试使用 PHPUnit 对其进行单元测试 请注意 此 HTML 是浏览器看不到 所以 Selenium 不是这个问题的正确解决方案 我只关心比较实际的 HTML 结构 我在用着assert
  • 微软 CNG |如何将 PEM 编码的 ECDSA 私钥导入 MS Key Storage Provider

    我知道 MS CNG 私人有这种格式 BCRYPT ECCKEY BLOB BYTE X cbKey Big endian BYTE Y cbKey Big endian BYTE d cbKey Big endian 因此尝试导入以下关键