[英]window.crypto.subtle.importkey and sign issue
在 typescript 中,我有以下代碼使用 ecdsa 方法和 SHA-512 算法對消息進行簽名。
const pem = "-----BEGIN PRIVATE KEY-----\nByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgUIcMiv/YpEgR1CKRsL6sS85BVo6lYft/S5nIjTlCHvihRANCAATykP7bc8\n-----END PRIVATE KEY-----"
// fetch the part of the PEM string between header and footer
const pemHeader = "-----BEGIN PRIVATE KEY-----";
const pemFooter = "-----END PRIVATE KEY-----";
const pemContents = pem.substring(pemHeader.length, pem.length - pemFooter.length);
// base64 decode the string to get the binary data
const binaryDerString = window.atob(pemContents);
// convert from a binary string to an ArrayBuffer
const binaryDer = this.str2ab(binaryDerString);
return window.crypto.subtle.importKey(
"pkcs8",
binaryDer,
{
name: "RSA-PSS",
hash: "SHA-512",
},
true,
["sign"]
);
}
我有這種方法來簽署消息:
createSignature2(){
let privateKey = this.importPrivateKey();
console.log(privateKey)
let data = this.str2ab("Test buffer")
let sign = window.crypto.subtle.sign(
{
name: "ECDSA",
hash: {name: "SHA-512"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
},
privateKey, //from generateKey or importKey above
data //ArrayBuffer of data you want to sign
)
.then(function(signature){
//returns an ArrayBuffer containing the signature
console.log(new Uint8Array(signature));
})
.catch(function(err){
console.error(err);
});
}
我得到一個錯誤:
Argument of type 'Promise<CryptoKey>' is not assignable to parameter of type 'CryptoKey'.
Type 'Promise<CryptoKey>' is missing the following properties from type 'CryptoKey': algorithm, extractable, type, usages
我在這里錯過了什么?
謝謝,
密鑰導入不正確。 RSA-PSS
導入 RSA 密鑰(用於使用 RSASSA-PSS 作為填充的簽名/驗證)。 但是,對於 ECDSA,導入 RSA 密鑰沒有任何意義。 RSA和ECDSA是完全不同的算法。 必須導入 EC 密鑰而不是 RSA 密鑰,因此必須指定 EC 曲線。
關於發布的密鑰本身:正如評論中已經提到的,這不符合任何有效格式,它既不代表 RSA 也不代表 EC 密鑰。
另一點是關於使用的語法。 該代碼通常應用then()
,但也應用缺少await
關鍵字的結構。 在這里,應該一致地只使用async/await
(以正確的方式)或只使用then()
(s. here for the difference)。
此外,缺少str2ab()
。
以下代碼顯示了導入 EC 密鑰的示例,包括使用 ECDSA 簽名。 P-521用作曲線。 作為私鑰,應用 PKCS#8 格式的 PEM 編碼樣本 EC 密鑰。
在代碼中應用了async/await
語法(因為我認為這更清楚)。 str2ab()
取自 WebCrypto API 文檔。 ab2str()
是它的逆 function。 簽名為 Base64 編碼用於顯示:
(async () => { createSignature2(); // Fix: apply consistently async/await syntax async function createSignature2(){ const privateKey = await importPrivateKey(); console.log(privateKey) const data = str2ab("Test buffer") const sign = await window.crypto.subtle.sign({name: "ECDSA",hash: {name: "SHA-512"}}, privateKey, data); console.log(window.btoa(ab2str(sign))); } async function importPrivateKey() { const pem = `-----BEGIN PRIVATE KEY----- MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIA3G3l+QFixI4fD4zW lC9n7xnT/7MS4bm6Ge6KXPmesmy9AARSdysdhWLXq51hvd/4F4Rd+ZYWn8bdeN58 zOJdRAOhgYkDgYYABAGBW8V/nf4yXdePGpotIL8WNR1182yBdcztCpWQUkL9TOEy vhhnf8SwtRDglbjCBiVONw4+WjC3pRfo3yTmee+mEQE3peJArA1zOFz9WJZhigA9 aK3t8BUbisZ38C4jcRuGgaBYUvg3ndMdqZnsNdbcg7sKOM9szCUvzGWkIWn2l4lW zA== -----END PRIVATE KEY-----`; const pemHeader = "-----BEGIN PRIVATE KEY-----"; const pemFooter = "-----END PRIVATE KEY-----"; const pemContents = pem.substring(pemHeader.length, pem.length - pemFooter.length); const binaryDerString = window.atob(pemContents); const binaryDer = str2ab(binaryDerString); return await window.crypto.subtle.importKey("pkcs8", binaryDer,{name: "ECDSA",namedCurve: "P-521"}, true, ["sign"]); // Fix: import ECDSA key } function str2ab(str) { const buf = new ArrayBuffer(str.length); const bufView = new Uint8Array(buf); for (let i = 0, strLen = str.length; i < strLen; i++) { bufView[i] = str.charCodeAt(i); } return buf; } function ab2str(buf) { return String.fromCharCode.apply(null, new Uint8Array(buf)); } })();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.