2017-01-08 138 views
2

我將一個CryptoKey導出爲PEM樣式,現在我想將其導回。 我用下面的代碼生成我的鑰匙:使用Web加密導入PEM密鑰

function generate() { 
    return window.crypto.subtle.generateKey(
    { 
     name: "RSA-OAEP", 
     modulusLength: 2048, 
     publicExponent: new Uint8Array([0x01, 0x00, 0x01]), 
     hash: {name: "SHA-256"}, 
    }, 
    true, 
    ["encrypt", "decrypt"] 
    ).then(function (key) { 
     return key; 
    }) 
    .catch(function (err) { 
     console.error(err); 
    }); 
} 

而且我試圖導入使用下一個代碼的私有密鑰是字符串(PEM風格):

function importPrivateKey(pemKey) { 
return crypto.subtle.importKey("pkcs8", convertPemToBinary(pemKey), {name:"RSA-OAEP", hash:{name:"SHA-256"}}, true, ["encrypt", "decrypt"]);} 

不幸的是,它返回這個錯誤:

SyntaxError: Cannot create a key using the specified key usages. 

UPDATE

convertPemToBinary功能

function convertPemToBinary(pem) { 
var lines = pem.split('\n'); 
var encoded = ''; 
for (var i = 0; i < lines.length; i++) { 
    if (lines[i].trim().length > 0 && 
     lines[i].indexOf('-----BEGIN RSA PRIVATE KEY-----') < 0 && 
     lines[i].indexOf('-----BEGIN RSA PUBLIC KEY-----') < 0 && 
     lines[i].indexOf('-----BEGIN PUBLIC KEY-----') < 0 && 
     lines[i].indexOf('-----END PUBLIC KEY-----') < 0 && 
     lines[i].indexOf('-----BEGIN PRIVATE KEY-----') < 0 && 
     lines[i].indexOf('-----END PRIVATE KEY-----') < 0 && 
     lines[i].indexOf('-----END RSA PRIVATE KEY-----') < 0 && 
     lines[i].indexOf('-----END RSA PUBLIC KEY-----') < 0) { 
     encoded += lines[i].trim(); 
    } 
} 
return base64StringToArrayBuffer(encoded); 
} 

在convertPemToBinary功能使用的子功能:

function base64StringToArrayBuffer(b64str) { 
b64str = b64EncodeUnicode(b64str); 
var byteStr = atob(b64str); 
var bytes = new Uint8Array(byteStr.length); 
for (var i = 0; i < byteStr.length; i++) { 
    bytes[i] = byteStr.charCodeAt(i); 
} 
return bytes.buffer; 
} 


function b64EncodeUnicode(str) { 
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) { 
     return String.fromCharCode('0x' + p1); 
    })); 
} 

回答

1

你不能用RSA-OAEP私有密鑰進行加密。該問題可能是由於您在導入時在密鑰用法中設置了encrypt標記。

看到webcrypto規範,修訂版

部22.4 https://w3c.github.io/webcrypto/Overview.html#rsa-oaep

If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

功能base64StringToArrayBuffer不正確

b64str = b64EncodeUnicode(b64str); 
var byteStr = atob(b64str); 

PEM是base64編碼,功能b64EncodeUnicode被編碼內容兩次。

見我的答案在這裏https://stackoverflow.com/a/38714970/6371459包含一個完整的例子來生成RSA-OAEP鍵,出口,編碼到PEM,解碼和進口再次(注:不使用頭)

這兩條線

更換
function b64DecodeUnicode(str) { 
    return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) { 
     return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); 
    }).join('')); 
} 
+0

嗯,私鑰的密鑰槽應該解密嗎? – urb

+0

是的。設置密鑰用法'[「解密」]' – pedrofb

+0

它返回數據錯誤。 – urb