You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
John Shaver eb02693c1f Updated build status badge. 10 months ago
bin output der as binstr, add comment 10 months ago
fixtures update tests 10 months ago
lib correct format hint 10 months ago
.drone.yml Removed testing key sizes below 512. Added optional testing of larger keys. 10 months ago
README.md Updated build status badge. 10 months ago
index.js a squeaky clean start 10 months ago
package.json generate RSA keys with node 10.12+ 10 months ago
test.sh Removed testing key sizes below 512. Added optional testing of larger keys. 10 months ago

README.md

Rasha.js · Build Status

Sponsored by Root. Built for ACME.js and Greenlock.js

| ~550 lines of code | 3kb gzipped | 10kb minified | 18kb with comments |

RSA tools. Lightweight. Zero Dependencies. Universal compatibility.

  • Fast and Easy RSA Key Generation
  • PEM-to-JWK
  • JWK-to-PEM
  • SSH “pub” format
  • ECDSA
    • Need EC or ECDSA tools? Check out Eckles.js

Generate RSA Key

Achieves the fastest possible key generation using node’s native RSA bindings to OpenSSL, then converts to JWK for ease-of-use.

Rasha.generate({ format: 'jwk' }).then(function (keypair) {
  console.log(keypair.private);
  console.log(keypair.public);
});

options

  • format defaults to 'jwk'
    • 'pkcs1' (traditional)
    • 'pkcs8'
  • modulusLength defaults to 2048 (must not be lower)
    • generally you shouldn’t pick a larger key size - they’re slow
    • 2048 is more than sufficient
    • 3072 is way, way overkill and takes a few seconds to generate
    • 4096 can take about a minute to generate and is just plain wasteful

advanced options

These options are provided for debugging and should not be used.

  • publicExponent defaults to 65537 (0x10001)

PEM-to-JWK

  • PKCS#1 (traditional)
  • PKCS#8, SPKI/PKIX
  • 2048-bit, 3072-bit, 4096-bit (and ostensibily all others)
  • SSH (RFC4716), (RFC 4716/SSH2)
var Rasha = require('rasha');
var pem = require('fs')
  .readFileSync('./node_modles/rasha/fixtures/privkey-rsa-2048.pkcs1.pem', 'ascii');

Rasha.import({ pem: pem }).then(function (jwk) {
  console.log(jwk);
});
{
  "kty": "RSA",
  "n": "m2ttVBxPlWw06ZmGBWVDl...QlEz7UNNj9RGps_50-CNw",
  "e": "AQAB",
  "d": "Cpfo7Mm9Nu8YMC_xrZ54W...Our1IdDzJ_YfHPt9sHMQQ",
  "p": "ynG-t9HwKCN3MWRYFdnFz...E9S4DsGcAarIuOT2TsTCE",
  "q": "xIkAjgUzB1zaUzJtW2Zgv...38ahSrBFEVnxjpnPh1Q1c",
  "dp": "tzDGjECFOU0ehqtuqhcu...dVGAXJoGOdv5VpaZ7B1QE",
  "dq": "kh5dyDk7YCz7sUFbpsmu...aX9PKa12HFlny6K1daL48",
  "qi": "AlHWbx1gp6Z9pbw_1hlS...lhmIOgRApS0t9VoXtHhFU"
}

JWK-to-PEM

  • PKCS#1 (traditional)
  • PKCS#8, SPKI/PKIX
  • 2048-bit, 4096-bit (and ostensibily all others)
  • SSH (RFC4716), (RFC 4716/SSH2)
var Rasha = require('rasha');
var jwk = require('rasha/fixtures/privkey-rsa-2048.jwk.json');

Rasha.export({ jwk: jwk }).then(function (pem) {
  // PEM in PKCS1 (traditional) format
  console.log(pem);
});
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAm2ttVBxPlWw06ZmGBWVDlfjkPAJ4DgnY0TrDwtCohHzLxGhD
NzUJefLukC+xu0LBKylYojT5vTkxaOhxeSYo31syu4WhxbkTBLICOFcCGMob6pSQ
38P8LdAIlb0pqDHxEJ9adWomjuFf.....5cCBahfsiNtNR6WV1/iCSuINYs6uPdA
Jlw7hm9m8TAmFWWyfL0s7wiRvAYkQvpxetorTwHJVLabBDJ+WBOAY2enOLHIRQv+
atAvHrLXjkUdzF96o0icyF6n7QzGfUPmeWGYg6BEClLS31Whe0eEVQ==
-----END RSA PRIVATE KEY-----

Advanced Options

format: 'pkcs8':

The default output format pkcs1 (RSA-specific format) is used for private keys. Use format: 'pkcs8' to output in PKCS#8 format instead.

Rasha.export({ jwk: jwk, format: 'pkcs8' }).then(function (pem) {
  // PEM in PKCS#8 format
  console.log(pem);
});
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCba21UHE+VbDTp
mYYFZUOV+OQ8AngOCdjROsPC0KiEfMvEaEM3NQl58u6QL7G7QsErKViiNPm9OTFo
6HF5JijfWzK7haHFuRMEsgI4VwIY.....LorV1ovjwKBgAJR1m8dYKemfaW8P9YZ
Uux7lwIFqF+yI201HpZXX+IJK4g1izq490AmXDuGb2bxMCYVZbJ8vSzvCJG8BiRC
+nF62itPAclUtpsEMn5YE4BjZ6c4schFC/5q0C8esteORR3MX3qjSJzIXqftDMZ9
Q+Z5YZiDoEQKUtLfVaF7R4RV
-----END PRIVATE KEY-----

format: 'ssh':

Although SSH uses PKCS#1 for private keys, it uses ts own special non-ASN1 format (affectionately known as rfc4716) for public keys. I got curious and then decided to add this format as well.

To get the same format as you would get with ssh-keygen, pass ssh as the format option:

Rasha.export({ jwk: jwk, format: 'ssh' }).then(function (pub) {
  // Special SSH2 Public Key format (RFC 4716)
  console.log(pub);
});
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCba21UHE.....Q02P1Eamz/nT4I3 rsa@localhost

public: 'true':

If a private key is used as input, a private key will be output.

If you’d like to output a public key instead you can pass public: true.

or format: 'spki'.

Rasha.export({ jwk: jwk, public: true }).then(function (pem) {
  // PEM in SPKI/PKIX format
  console.log(pem);
});
-----BEGIN PUBLIC KEY-----
MIIBCgKCAQEAm2ttVBxPlWw06ZmGBWVDlfjkPAJ4DgnY0TrDwtCohHzLxGhDNzUJ
efLukC+xu0LBKylYojT5vTkxaOhx.....TmzCh2ikrwTMja7mUdBJf2bK3By5AB0
Qi49OykUCfNZeQlEz7UNNj9RGps/50+CNwIDAQAB
-----END PUBLIC KEY-----

Testing

All cases are tested in test.sh.

You can compare these keys to the ones that you get from OpenSSL, OpenSSH/ssh-keygen, and WebCrypto:

# Generate 2048-bit RSA Keypair
openssl genrsa -out privkey-rsa-2048.pkcs1.pem 2048

# Convert PKCS1 (traditional) RSA Keypair to PKCS8 format
openssl rsa -in privkey-rsa-2048.pkcs1.pem -pubout -out pub-rsa-2048.spki.pem

# Export Public-only RSA Key in PKCS1 (traditional) format
openssl pkcs8 -topk8 -nocrypt -in privkey-rsa-2048.pkcs1.pem -out privkey-rsa-2048.pkcs8.pem

# Convert PKCS1 (traditional) RSA Public Key to SPKI/PKIX format
openssl rsa -in pub-rsa-2048.spki.pem -pubin -RSAPublicKey_out -out pub-rsa-2048.pkcs1.pem

# Convert RSA public key to SSH format
ssh-keygen -f ./pub-rsa-2048.spki.pem -i -mPKCS8 > ./pub-rsa-2048.ssh.pub

Goals of this project

  • Focused support for 2048-bit and 4096-bit RSA keypairs (although any size is technically supported)
  • Zero Dependencies
  • VanillaJS
  • Quality Code: Good comments and tests
  • Convert both ways: PEM-to-JWK and JWK-to-PEM (also supports SSH pub files)
  • Browser support as well (TODO)
  • OpenSSL, ssh-keygen, and WebCrypto compatibility

Legal

Rasha.js | MPL-2.0 | Terms of Use | Privacy Policy