我想从输入键材料(主键)派生椭圆曲线私钥。这可能吗?

尝试次数

Node的加密函数crypto.generateKeyPair不接受输入密钥材料,并且crypto.createPrivateKey仅将.pem转换为Node的本机KeyObject。

我也找不到使用ecparam在OpenSSL中执行此操作的方法。 -rand标志似乎很有希望,但并未广泛使用(它不在我的计算机上)。

为什么/详细信息

我需要创建许多秘密,并希望所有秘密都来自一个主密钥。这类似于HKDF。

我正在使用曲线P-384(secp384r1)的ECDSA密钥。

最佳答案

我很惊讶您认为ecparam -rand file -genkey ...很少见;它在每个上游版本中至少都可以追溯到2005年的0.9.8,这不是可以通过build(配置)选项忽略的事情之一,因此您的计算机必须具有一个怪异的版本。但这没关系,因为-rand不会执行您想要的操作;它将文件数据添加到RNG“池”,但不会替换它,因此不会为您提供确定性的密钥生成。

正如伍德斯托克(Woodstock)所评论的那样,出于所有实际目的,原始P-384私钥仅来自任何良好随机发生器的384位,或者确定地来自任何统一随机函数的384位。从技术上讲,您应该排除零且值大于或等于(子)组阶数n,但是相对于2 ^ 384而言,这些排除项是如此之小,以至于基本上没有机会在地球的生命周期内碰到一个好的随机选择,也许是宇宙的。您可能想看一下比特币“分层确定性”密钥推导(又称为BIP 32)的工作原理,尽管当然可以对secp256k1执行256位密钥。

剩下的问题是将原始密钥转换为nodejs crypto(openssl库的相当薄的包装)和/或openssl命令行可用的形式。为此,请遵循How to convert an ECDSA key to PEM format的原则,该原则又基于https://bitcoin.stackexchange.com/questions/66594/signing-transaction-with-ssl-private-key-to-pem,但对于P-384而不是secp256k1,请使用OID和大小。具体来说,串联


303e0201010430以十六进制表示的7个字节
原始私钥的48个字节(384位)
a00706052b81040022以十六进制表示的9个字节(适用于P-384,也称为secp384r1)


根据您的语言或工具,您可以直接处理这些值,或者连接十六进制表示形式,然后转换为二进制。结果是算法专用(SEC1)私钥(仅)的“ DER”(二进制)形式(只能由nodejs 11或12 crypto.createPrivateKey( {key:(data), format:'der', type:'sec1'} )以及命令行openssl ec -inform der读取)。

如果您喜欢文本式的东西(例如,用于剪切和粘贴),请将上面的DER转换为base64,分成64个字符的行(最后一个字符除外),然后在行前添加-----BEGIN EC PRIVATE KEY-----,在其后添加-----END EC PRIVATE KEY------。这是PEM格式,可以由createPrivateKey读取而没有任何其他选项,而由openssl ec读取而没有任何选项。

关于node.js - 根据NodeJS中的输入 key Material 创建EC私钥,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58018731/

10-09 22:20