2017-01-08 143 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