diafygi / webcrypto-examples

Web Cryptography API Examples Demo: https://diafygi.github.io/webcrypto-examples/
GNU General Public License v2.0
1.64k stars 193 forks source link

How import (e,n) RSA public key to web crypto? #7

Closed BaurzhanSakhariev closed 9 years ago

BaurzhanSakhariev commented 9 years ago

I'm sorry for asking almost similar question to the previous one but I couldn't resolve it by myself.

How RSA public key to web crypto? pkcs#8 relevant only for private key, for public keys I may specify "raw" or "spki". I tried stripped and not stripped PEM with importKey("raw"...), no success. I also tried "raw" and ArrayBuffer(pubKeytoAsn->toDer.getBytes) and again failed.

It seems I have to manually construct JSON parameter in the example below.

window.crypto.subtle.importKey(
"jwk", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
{   //this is an example jwk key, other key types are Uint8Array objects
    kty: "RSA",
    e: "AQAB",
    n: "vGO3eU16ag9zRkJ4AK8ZUZrjbtp5xWK0LyFMNT8933evJoHeczexMUzSiXaLrEFSyQZortk81zJH3y41MBO_UFDO_X0crAquNrkjZDrf9Scc5-MdxlWU2Jl7Gc4Z18AC9aNibWVmXhgvHYkEoFdLCFG-2Sq-qIyW4KFkjan05IE",
    alg: "RS256",
    ext: true,
},

A saw n and e attributes in my public key but I didn't understand is 'n' valuein JSON a base64 of key's n-array which has 74 elements?

In short, I have e=65537, n=array of 74 integers, how can I convert it to jwk? My algo params are "RSASSA-PKCS1-v1_5", hash: {name: "SHA-256"}.

Thanks.

diafygi commented 9 years ago

You need to base64 encode the integers using the urlsafe base64 encoding method described in the JWK spec.

https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#appendix-C

Here's a way to do it:

//Adapted from http://stackoverflow.com/a/9458996
function _arrayBufferToJwkBase64( buffer ) {
    var binary = '';
    var bytes = new Uint8Array( buffer );
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode( bytes[ i ] );
    }
    var base64 = window.btoa( binary );
    var jwk_base64 = base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');
    return jwk_base64;
}

var e = [1, 0, 1];
var n = [
    188, 99, 183, 121, 77, 122, 106, 15, 115, 70, 66, 120,
    0, 175, 25, 81, 154, 227, 110, 218, 121, 197, 98, 180,
    47, 33, 76, 53, 63, 61, 223, 119, 175, 38, 129, 222, 115,
    55, 177, 49, 76, 210, 137, 118, 139, 172, 65, 82, 201, 6,
    104, 174, 217, 60, 215, 50, 71, 223, 46, 53, 48, 19, 191,
    80, 80, 206, 253, 125, 28, 172, 10, 174, 54, 185, 35, 100,
    58, 223, 245, 39, 28, 231, 227, 29, 198, 85, 148, 216, 153,
    123, 25, 206, 25, 215, 192, 2, 245, 163, 98, 109, 101, 102,
    94, 24, 47, 29, 137, 4, 160, 87, 75, 8, 81, 190, 217, 42,
    190, 168, 140, 150, 224, 161, 100, 141, 169, 244, 228, 129
];
var jwk_pubkey = {
    kty: "RSA",
    e: _arrayBufferToJwkBase64(e),
    n: _arrayBufferToJwkBase64(n),
    alg: "RS256",
    ext: true,
};
BaurzhanSakhariev commented 9 years ago

Thanks!