2015-11-16 12 views
0

Я пытаюсь сгенерировать ключ RSA с помощью Web Crypto и использовать его для подписи строки с помощью jsrsasign (Firefox does not support RSA-PSS). Поэтому экспортировать ключ веб-Crypto и преобразовать его в PKCS8-PEM, но когда я звоню KEYUTIL.getKeyFromPlainPrivatePKCS8PEM импортировать ключ jsrsasign ошибку брошено: уродливы простой PKCS8 закрытый ключ (код: 001)Как экспортировать ключ Crypto в jsrsasign

Что Я неправ? JSBin

window.crypto.subtle.generateKey(
    { 
    name: "RSA-OAEP", 
    modulusLength: 2048, 
    publicExponent: new Uint8Array([0x01, 0x00, 0x01]), 
    hash: {name: "SHA-256"}, 
    }, 
    true, 
    ["encrypt", "decrypt"] 
) 
.then(keyPair => window.crypto.subtle.exportKey("pkcs8", keyPair.privateKey)) 
.then(arrayBufferToBase64String) 
.then(toPem) 
.then(pem => { 
    var rsa = KEYUTIL.getKeyFromPlainPrivatePKCS8PEM(pem); // throws: malformed plain PKCS8 private key(code:001) 
    var sig = rsa.signStringPSS('text', 'sha256', 32); 
    console.log('signature', sig); 
}) 
.catch(::console.error) 

function arrayBufferToString(arrayBuffer) { 
    var byteArray = new Uint8Array(arrayBuffer) 
    var byteString = ''; 
    for (var i=0; i<byteArray.byteLength; i++) { 
    byteString += String.fromCharCode(byteArray[i]); 
    } 
    return byteString; 
} 

function arrayBufferToBase64String(arrayBuffer) { 
    return btoa(arrayBufferToString(arrayBuffer)); 
} 

function toPem(key) { 
    return ` 
-----BEGIN RSA PRIVATE KEY----- 
${key} 
-----END RSA PRIVATE KEY----- 
`; 
} 

Edit:

Я просто понял, что jsrsasign может обрабатывать JWK:

window.crypto.subtle.generateKey(
    { 
    name: "RSA-OAEP", 
    modulusLength: 2048, 
    publicExponent: new Uint8Array([0x01, 0x00, 0x01]), 
    hash: {name: "SHA-256"}, 
    }, 
    true, 
    ["encrypt", "decrypt"] 
) 
.then(keyPair => window.crypto.subtle.exportKey("jwk", keyPair.privateKey)) 
.then(jwk => { 
    var rsa = KEYUTIL.getKey(jwk); 
    var sig = rsa.signStringPSS('text', 'sha256', 32); 
    console.log('signature', sig); 
}) 
.catch(::console.error) 

Я предпочитаю это решение, но я все же хотел бы знать, почему мое решение pkcs8 делает не работа.

ответ

1

Ваш шифрованный ключ PEM является фактически PKCS # 1, а не PKCS # 8 из-за части RSA. Это всего лишь ключевой объект RSA в DER без идентификатора ключа, завернутого в последовательность.

jsrsasign ищет заголовок PKCS # 8 «НАЧАТЬ ЧАСТНЫЙ КЛЮЧ», а не «НАЧАТЬ ЧАСТНЫЙ КЛЮЧ RSA». Изменение заголовка заставляет его работать.

2

Это не работает, изменяя заголовок PEM с "----BEGIN RSA PRIVATE KEY-----" до "-----BEGIN PRIVATE KEY-----", так как контент отличается. Я думаю, что использование JWK для экспорта файлов - лучший способ сделать это, поскольку он будет иметь большую функциональную совместимость между любыми браузерами. Я пробовал то же самое, прежде чем PKCS # 8 не работает в некоторых браузерах.

Как описано Felix, ваш RSA ключ является PKCS # 1 ключ, который имеет "-----BEGIN RSA PRIVATE KEY-----"PEM заголовок.

Если вам нужно конвертировать PKCS # 1 в PKCS # 8 ключ KEYUTIL класс может быть полезен как в этом примере:

keyobj = KEYUTIL.getKey("-----BEGIN RSA PRIVATE KEY-----..."); // your key 
pkcs8pem = KEYUTIL.getPEM(keyobj, "PKCS8PRV"); 

 Смежные вопросы

  • Нет связанных вопросов^_^