這個問題是從 Information Security Stack Exchange遷移過來的,因為它可以在 Stack Overflow 上回答。 7 天前遷移 。
我正在使用命令創建一個私有 EC 密鑰openssl ecparam -name secp256r1 -genkey -noout -out k1.pem。我正在嘗試crypto.subtle.importKey按照本檔案中的說明匯入它。
即在運行 OpenSSL 后我有私鑰
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIOuQ2Du5Q3bE0wzYwqImGjbb6zASbof36MVeRQMTfOA5oAoGCCqGSM49
AwEHoUQDQgAErSz9FIO1sLPciJjHbj/EduYNClaeCBhQuU5ZPh24YRvHG5FXLNiV
1dPIB02KyKXiYjvLro586uYDkYzaPkzbOw==
-----END EC PRIVATE KEY-----
并從 Chrome 控制臺
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 代碼成功匯入它:
(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 "x" 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-----"))))
uj5u.com熱心網友回復:
這是 SEC1 格式的私有 EC 密鑰,WebCrypto 不支持。這里是支持的格式。
WebCrypto 支持的私鑰格式是 PKCS#8(順便說一下,您已經在 WebCrypto 代碼中將其用作importKey()呼叫中的第一個引數),因此可能的解決方法是將密鑰轉換為這種格式,例如使用 OpenSSL:
openssl pkcs8 -topk8 -nocrypt -in <path to input-sec1-pem> -out <path to output-pkcs8-pem>
這使:
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg65DYO7lDdsTTDNjC
oiYaNtvrMBJuh/foxV5FAxN84DmhRANCAAStLP0Ug7Wws9yImMduP8R25g0KVp4I
GFC5Tlk HbhhG8cbkVcs2JXV08gHTYrIpeJiO8uujnzq5gORjNo TNs7
-----END PRIVATE KEY-----
兩種格式都表示相同的密鑰(即封裝相同的密鑰引數,即相同的原始私鑰和相同的原始公鑰),可以在 ASN.1 決議器中驗證(例如https://lapo.it/asn1js/)
使用 PKCS#8 格式的密鑰匯入成功:
(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);
})();
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/504918.html
