💯 RSA tools. Lightweight. Zero Dependencies. Great tests. Universal compatibility.
rsa
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.

README.md 6.2 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. [Rasha.js](https://git.coolaj86.com/coolaj86/rasha.js)
  2. =========
  3. A [Root](https://therootcompany.com) Project.
  4. Built for [ACME.js](https://git.coolaj86.com/coolaj86/acme.js)
  5. and [Greenlock.js](https://git.coolaj86.com/coolaj86/greenlock.js)
  6. | ~550 lines of code | 3kb gzipped | 10kb minified | 18kb with comments |
  7. RSA tools. Lightweight. Zero Dependencies. Universal compatibility.
  8. * [x] Fast and Easy RSA Key Generation
  9. * [x] PEM-to-JWK
  10. * [x] JWK-to-PEM
  11. * [x] JWK thumbprint
  12. * [x] SSH "pub" format
  13. * [ ] ECDSA
  14. * **Need EC or ECDSA tools?** Check out [Eckles.js](https://git.coolaj86.com/coolaj86/eckles.js)
  15. ## Generate RSA Key
  16. Achieves the *fastest possible key generation* using node's native RSA bindings to OpenSSL,
  17. then converts to JWK for ease-of-use.
  18. ```
  19. Rasha.generate({ format: 'jwk' }).then(function (keypair) {
  20. console.log(keypair.private);
  21. console.log(keypair.public);
  22. });
  23. ```
  24. **options**
  25. * `format` defaults to `'jwk'`
  26. * `'pkcs1'` (traditional)
  27. * `'pkcs8'` <!-- * `'ssh'` -->
  28. * `modulusLength` defaults to 2048 (must not be lower)
  29. * generally you shouldn't pick a larger key size - they're slow
  30. * **2048** is more than sufficient
  31. * 3072 is way, way overkill and takes a few seconds to generate
  32. * 4096 can take about a minute to generate and is just plain wasteful
  33. **advanced options**
  34. These options are provided for debugging and should not be used.
  35. * `publicExponent` defaults to 65537 (`0x10001`)
  36. ## PEM-to-JWK
  37. * [x] PKCS#1 (traditional)
  38. * [x] PKCS#8, SPKI/PKIX
  39. * [x] 2048-bit, 3072-bit, 4096-bit (and ostensibily all others)
  40. * [x] SSH (RFC4716), (RFC 4716/SSH2)
  41. ```js
  42. var Rasha = require('rasha');
  43. var pem = require('fs')
  44. .readFileSync('./node_modles/rasha/fixtures/privkey-rsa-2048.pkcs1.pem', 'ascii');
  45. Rasha.import({ pem: pem }).then(function (jwk) {
  46. console.log(jwk);
  47. });
  48. ```
  49. ```js
  50. {
  51. "kty": "RSA",
  52. "n": "m2ttVBxPlWw06ZmGBWVDl...QlEz7UNNj9RGps_50-CNw",
  53. "e": "AQAB",
  54. "d": "Cpfo7Mm9Nu8YMC_xrZ54W...Our1IdDzJ_YfHPt9sHMQQ",
  55. "p": "ynG-t9HwKCN3MWRYFdnFz...E9S4DsGcAarIuOT2TsTCE",
  56. "q": "xIkAjgUzB1zaUzJtW2Zgv...38ahSrBFEVnxjpnPh1Q1c",
  57. "dp": "tzDGjECFOU0ehqtuqhcu...dVGAXJoGOdv5VpaZ7B1QE",
  58. "dq": "kh5dyDk7YCz7sUFbpsmu...aX9PKa12HFlny6K1daL48",
  59. "qi": "AlHWbx1gp6Z9pbw_1hlS...lhmIOgRApS0t9VoXtHhFU"
  60. }
  61. ```
  62. ## JWK-to-PEM
  63. * [x] PKCS#1 (traditional)
  64. * [x] PKCS#8, SPKI/PKIX
  65. * [x] 2048-bit, 4096-bit (and ostensibily all others)
  66. * [x] SSH (RFC4716), (RFC 4716/SSH2)
  67. ```js
  68. var Rasha = require('rasha');
  69. var jwk = require('rasha/fixtures/privkey-rsa-2048.jwk.json');
  70. Rasha.export({ jwk: jwk }).then(function (pem) {
  71. // PEM in PKCS1 (traditional) format
  72. console.log(pem);
  73. });
  74. ```
  75. ```
  76. -----BEGIN RSA PRIVATE KEY-----
  77. MIIEpAIBAAKCAQEAm2ttVBxPlWw06ZmGBWVDlfjkPAJ4DgnY0TrDwtCohHzLxGhD
  78. NzUJefLukC+xu0LBKylYojT5vTkxaOhxeSYo31syu4WhxbkTBLICOFcCGMob6pSQ
  79. 38P8LdAIlb0pqDHxEJ9adWomjuFf.....5cCBahfsiNtNR6WV1/iCSuINYs6uPdA
  80. Jlw7hm9m8TAmFWWyfL0s7wiRvAYkQvpxetorTwHJVLabBDJ+WBOAY2enOLHIRQv+
  81. atAvHrLXjkUdzF96o0icyF6n7QzGfUPmeWGYg6BEClLS31Whe0eEVQ==
  82. -----END RSA PRIVATE KEY-----
  83. ```
  84. ### Advanced Options
  85. `format: 'pkcs8'`:
  86. The default output format `pkcs1` (RSA-specific format) is used for private keys.
  87. Use `format: 'pkcs8'` to output in PKCS#8 format instead.
  88. ```js
  89. Rasha.export({ jwk: jwk, format: 'pkcs8' }).then(function (pem) {
  90. // PEM in PKCS#8 format
  91. console.log(pem);
  92. });
  93. ```
  94. ```
  95. -----BEGIN PRIVATE KEY-----
  96. MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCba21UHE+VbDTp
  97. mYYFZUOV+OQ8AngOCdjROsPC0KiEfMvEaEM3NQl58u6QL7G7QsErKViiNPm9OTFo
  98. 6HF5JijfWzK7haHFuRMEsgI4VwIY.....LorV1ovjwKBgAJR1m8dYKemfaW8P9YZ
  99. Uux7lwIFqF+yI201HpZXX+IJK4g1izq490AmXDuGb2bxMCYVZbJ8vSzvCJG8BiRC
  100. +nF62itPAclUtpsEMn5YE4BjZ6c4schFC/5q0C8esteORR3MX3qjSJzIXqftDMZ9
  101. Q+Z5YZiDoEQKUtLfVaF7R4RV
  102. -----END PRIVATE KEY-----
  103. ```
  104. `format: 'ssh'`:
  105. Although SSH uses PKCS#1 for private keys, it uses ts own special non-ASN1 format
  106. (affectionately known as rfc4716) for public keys. I got curious and then decided
  107. to add this format as well.
  108. To get the same format as you
  109. would get with `ssh-keygen`, pass `ssh` as the format option:
  110. ```js
  111. Rasha.export({ jwk: jwk, format: 'ssh' }).then(function (pub) {
  112. // Special SSH2 Public Key format (RFC 4716)
  113. console.log(pub);
  114. });
  115. ```
  116. ```
  117. ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCba21UHE.....Q02P1Eamz/nT4I3 rsa@localhost
  118. ```
  119. `public: 'true'`:
  120. If a private key is used as input, a private key will be output.
  121. If you'd like to output a public key instead you can pass `public: true`.
  122. or `format: 'spki'`.
  123. ```js
  124. Rasha.export({ jwk: jwk, public: true }).then(function (pem) {
  125. // PEM in SPKI/PKIX format
  126. console.log(pem);
  127. });
  128. ```
  129. ```
  130. -----BEGIN PUBLIC KEY-----
  131. MIIBCgKCAQEAm2ttVBxPlWw06ZmGBWVDlfjkPAJ4DgnY0TrDwtCohHzLxGhDNzUJ
  132. efLukC+xu0LBKylYojT5vTkxaOhx.....TmzCh2ikrwTMja7mUdBJf2bK3By5AB0
  133. Qi49OykUCfNZeQlEz7UNNj9RGps/50+CNwIDAQAB
  134. -----END PUBLIC KEY-----
  135. ```
  136. ## JWK Thumbprint
  137. ```js
  138. Rasha.thumbprint({ jwk: jwk }).then(function (thumbprint) {
  139. console.log(thumbprint);
  140. });
  141. ```
  142. Testing
  143. -------
  144. All cases are tested in `test.sh`.
  145. You can compare these keys to the ones that you get from OpenSSL, OpenSSH/ssh-keygen, and WebCrypto:
  146. ```bash
  147. # Generate 2048-bit RSA Keypair
  148. openssl genrsa -out privkey-rsa-2048.pkcs1.pem 2048
  149. # Convert PKCS1 (traditional) RSA Keypair to PKCS8 format
  150. openssl rsa -in privkey-rsa-2048.pkcs1.pem -pubout -out pub-rsa-2048.spki.pem
  151. # Export Public-only RSA Key in PKCS1 (traditional) format
  152. openssl pkcs8 -topk8 -nocrypt -in privkey-rsa-2048.pkcs1.pem -out privkey-rsa-2048.pkcs8.pem
  153. # Convert PKCS1 (traditional) RSA Public Key to SPKI/PKIX format
  154. openssl rsa -in pub-rsa-2048.spki.pem -pubin -RSAPublicKey_out -out pub-rsa-2048.pkcs1.pem
  155. # Convert RSA public key to SSH format
  156. ssh-keygen -f ./pub-rsa-2048.spki.pem -i -mPKCS8 > ./pub-rsa-2048.ssh.pub
  157. ```
  158. Goals of this project
  159. -----
  160. * Focused support for 2048-bit and 4096-bit RSA keypairs (although any size is technically supported)
  161. * Zero Dependencies
  162. * VanillaJS
  163. * Quality Code: Good comments and tests
  164. * Convert both ways: PEM-to-JWK and JWK-to-PEM (also supports SSH pub files)
  165. * Browser support as well (TODO)
  166. * OpenSSL, ssh-keygen, and WebCrypto compatibility
  167. Legal
  168. -----
  169. [Rasha.js](https://git.coolaj86.com/coolaj86/rasha.js) |
  170. MPL-2.0 |
  171. [Terms of Use](https://therootcompany.com/legal/#terms) |
  172. [Privacy Policy](https://therootcompany.com/legal/#privacy)