我只希望有一对密钥,可用于ECDH函数和node:crypto
模块中的其他函数。
我知道用node:crypto
模块生成密钥有两种方法。
一种方法是使用crypto.generateKeyPairSync
,它生成的密钥格式几乎为node:crypto
模块中的所有加密函数所接受:
const crypto = require('node:crypto')
const {publicKey, privateKey} = crypto.generateKeyPairSync('ec', {
namedCurve: 'secp224r1'
})
const pubKey = publicKey.export({type: 'spki', format: 'pem'}).toString()
const privKey = privateKey.export({type: 'pkcs8', format: 'pem'}).toString()
这将以pem格式输出密钥。
但是如果我想使用ECDH,我需要以下面的方式生成密钥:
const crypto = require('node:crypto')
const ecdh = crypto.createECDH('secp224r1')
ecdh.generateKeys()
const rawPublic = ecdh.getPublicKey('base64', 'uncompressed')
const rawPrivate = ecdh.getPrivateKey('base64')
它只生成原始密钥。
如何从原始密钥生成PEM或从PEM生成原始密钥,以便我可以只使用一组密钥,而不是为ECDH生成新的密钥组?
1条答案
按热度按时间yx2lnoni1#
加密模块不直接支持转换ASN.1/DER <->raw。支持此转换的第三方库是eckey-utils。
从原始密钥到PEM密钥的转换是可能的,例如如下所述。
因此,私钥以SEC 1格式导出。如果需要PKCS#8格式,则可以使用加密模块进行转换:
反之则为:
如果私钥为PKCS#8格式,则必须事先转换为SEC 1格式:
注意,在
parsePem()
中使用之前,这里需要一个trim()
来删除尾随换行符(0x0a
),而parsePem()
不允许这样做。用于将原始密钥转换成PEM密钥的另一种方法是替换嵌入在ASN.1/DER字节序列中的原始密钥,例如在下面用于将原始私有密钥转换成PKCS#8密钥(其还包含公共密钥)以及将原始公共密钥转换成用于曲线secp 224 r1的X.509/SPKI密钥:
对于相反方向,可以在ASN.1/DER编码中原始密钥的相应位置提取原始密钥。
这种方法的优点是没有依赖性,缺点是
privA
、privB
和pubA
是包含元数据的ASN.1/DER编码,元数据例如是曲线或长度信息(当检查ASN.1解析器中的PEM键时可以看到,例如https://lapo.it/asn1js/),因此它们对于每条曲线是不同的。