首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法将OpenSSL生成的私钥导入web crypto.subtle.importKey

无法将OpenSSL生成的私钥导入web crypto.subtle.importKey
EN

Stack Overflow用户
提问于 2022-08-30 14:06:45
回答 1查看 63关注 0票数 0

我正在使用命令openssl ecparam -name secp256r1 -genkey -noout -out k1.pem创建一个私有EC密钥。我正在尝试使用crypto.subtle.importKey导入它,如这份文件中所描述的。

也就是说,在运行OpenSSL之后,我有一个私钥

代码语言:javascript
运行
复制
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIOuQ2Du5Q3bE0wzYwqImGjbb6zASbof36MVeRQMTfOA5oAoGCCqGSM49
AwEHoUQDQgAErSz9FIO1sLPciJjHbj/EduYNClaeCBhQuU5ZPh24YRvHG5FXLNiV
1dPIB02KyKXiYjvLro586uYDkYzaPkzbOw==
-----END EC PRIVATE KEY-----

从Chrome控制台

代码语言:javascript
运行
复制
let binary = atob("MHcCAQEEIOuQ2Du5Q3bE0wzYwqImGjbb6zASbof36MVeRQMTfOA5oAoGCCqGSM49AwEHoUQDQgAErSz9FIO1sLPciJjHbj/EduYNClaeCBhQuU5ZPh24YRvHG5FXLNiV1dPIB02KyKXiYjvLro586uYDkYzaPkzbOw==")
let der = str2ab(binary)
let key = crypto.subtle.importKey(
    'pkcs8',
    der,
    {
      name: 'ECDSA',
      namedCurve: 'P-256',
    },
    false,
    ['sign']
  );

从最后一个命令中获得一个Uncaught (in promise) Error

值得一提的是,当我通过Clojure使用Java库生成EC密钥时,我可以使用相同的js代码成功地导入它:

代码语言:javascript
运行
复制
(ns vouch.crypto
  (:import (java.security KeyPairGenerator SecureRandom KeyPair)
           (org.bouncycastle.jce ECNamedCurveTable)
           (java.util Base64)))

(defn generate-ec-key-pair
  "Generate an Elliptic Curve Key Pair"
  ^KeyPair []
  (let [ec-spec (ECNamedCurveTable/getParameterSpec "secp256r1")
        ^KeyPairGenerator generator (KeyPairGenerator/getInstance "ECDSA" "BC")]
    (.initialize generator ec-spec (SecureRandom.))
    (.generateKeyPair generator)))

(defn bytes->hex
  "Convert a seq of bytes into a hex encoded string."
  ^String [^bytes bytes]
  (apply str (for [b bytes] (format "%02x" b))))

(defn- base64-encode
  ^String [^bytes bytes-to-encode]
  (-> (Base64/getEncoder)
      (.encode bytes-to-encode)
      (String. StandardCharsets/UTF_8)))

(comment
  (let [key-pair           (vouch.crypto/generate-ec-key-pair)
        private-key        (.getPrivate key-pair)
        private-key-base64 (-> private-key .getEncoded vouch.crypto/base64-encode)]
    (println (str "-----BEGIN EC PRIVATE KEY-----\n" private-key-base64 "\n-----END EC PRIVATE KEY-----"))))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-30 14:46:44

这是一个SEC1格式的私有EC密钥,支持的格式不受WebCrypto,s. 这里的支持。

WebCrypto为私钥支持的一种格式是PKCS#8 (顺便说一句,您已经在WebCrypto代码中使用它作为importKey()调用中的第一个参数),因此可能的解决办法是将密钥转换为这种格式,例如使用OpenSSL:

代码语言:javascript
运行
复制
openssl pkcs8 -topk8 -nocrypt -in <path to input-sec1-pem> -out <path to output-pkcs8-pem>

这意味着:

代码语言:javascript
运行
复制
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg65DYO7lDdsTTDNjC
oiYaNtvrMBJuh/foxV5FAxN84DmhRANCAAStLP0Ug7Wws9yImMduP8R25g0KVp4I
GFC5Tlk+HbhhG8cbkVcs2JXV08gHTYrIpeJiO8uujnzq5gORjNo+TNs7
-----END PRIVATE KEY-----

这两种格式表示可以在ASN.1解析器(例如https://lapo.it/asn1js/)中验证的相同密钥(即封装相同的密钥参数,即相同的原始私钥和相同的原始公钥)。

使用PKCS#8格式的键导入是成功的:

代码语言:javascript
运行
复制
(async () => {

    function b642ab(base64_string){
        return Uint8Array.from(window.atob(base64_string), c => c.charCodeAt(0));
    }

    let der = b642ab("MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg65DYO7lDdsTTDNjCoiYaNtvrMBJuh/foxV5FAxN84DmhRANCAAStLP0Ug7Wws9yImMduP8R25g0KVp4IGFC5Tlk+HbhhG8cbkVcs2JXV08gHTYrIpeJiO8uujnzq5gORjNo+TNs7")
    let key = await crypto.subtle.importKey(
        'pkcs8',
        der,
        {
            name: 'ECDSA',
            namedCurve: 'P-256',
        },
        false,
        ['sign']
    );

    console.log(key);

})();

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73543963

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档