refactor: finish moving ssh-* scripts to own installers
[webi-installers/.git] / keypairs / README.md
1 ---
2 title: keypairs
3 homepage: https://github.com/therootcompany/keypairs
4 tagline: |
5   keypairs: a cross-platform tool for RSA, ECDSA, JWT, JOSE, and general asymmetric encryption
6 ---
7
8 To update or switch versions, run `webi keypairs@stable`.
9
10 ## Cheat Sheet
11
12 > keypairs is like JWT.io, at your fingertips.
13
14 - Generates NIST standard RSA and ECDSA keys
15 - Signatures output as JWT and JWS (JSONE)
16 - Verifies signatures
17
18 ### How to generate JSON Web Keys (JWKs)
19
20 ```bash
21 # keypairs gen -key <key.format> -pub <pub.format>
22 keypairs gen -key key.jwk.json -pub pub.jwk.json
23 ```
24
25 JWK is the default format, for which you can use stdout (key) and stderr (pub)
26
27 ```bash
28 keypairs gen > key.jwk.json 2> pub.jwk.json
29 ```
30
31 ### How to generate PEM (PKCS) keys
32
33 ```bash
34 keypairs gen -key key.pem -pub pub.pem
35 ```
36
37 Or DER
38
39 ```bash
40 keypairs gen -key key.der -pub pub.der
41 ```
42
43 ### How to sign a payload
44
45 ```bash
46 # keypairs sign --exp 1h <priv key> <data or file> > token.jwt 2> sig.jws
47 keypairs sign --exp 1h key.jwk.json '{ "sub": "me@example.com" }' > token.jwt 2> sig.jws
48 ```
49
50 A JWT (JSON Web Token) has 3 sections (protected header, payload, and signature)
51 separated by dots (`.`):
52
53 ```txt
54 eyJhbGciOiJFUzI1NiIsImtpZCI6ImpkeHhZY1NCZUJfeUdoZWlCVW14NjF0eHExZGFjR1hIX191bEJuWlZHMEUiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjIxNDczODU3MTIsInN1YiI6Im1lQGV4YW1wbGUuY29tIn0.oh8-PUMdrbQU6seRXjo68wPWAKbA-V9LMnd_wZEkPHc3C8A5xJzV7mDDMNOLEy4VcuNGxced_yjYulzcMa5FLQ
55 ```
56
57 A JWS (JSON Web Signature), is just a parsed JWT:
58
59 ```json
60 {
61   "claims": {
62     "exp": 2147385712,
63     "sub": "me@example.com"
64   },
65   "header": {
66     "alg": "ES256",
67     "kid": "jdxxYcSBeB_yGheiBUmx61txq1dacGXH__ulBnZVG0E",
68     "typ": "JWT"
69   },
70   "payload": "eyJleHAiOjIxNDczODU3MTIsInN1YiI6Im1lQGV4YW1wbGUuY29tIn0",
71   "protected": "eyJhbGciOiJFUzI1NiIsImtpZCI6ImpkeHhZY1NCZUJfeUdoZWlCVW14NjF0eHExZGFjR1hIX191bEJuWlZHMEUiLCJ0eXAiOiJKV1QifQ",
72   "signature": "oh8-PUMdrbQU6seRXjo68wPWAKbA-V9LMnd_wZEkPHc3C8A5xJzV7mDDMNOLEy4VcuNGxced_yjYulzcMa5FLQ"
73 }
74 ```
75
76 Note that self-signed JWTs and JWSes will use `jwk` as the full public key
77 rather than the `kid` thumbprint.
78
79 ### How to verify a signature
80
81 ```bash
82 # keypairs verify <pub key> <signed file or data>
83 keypairs verify pub.jwk.json token.jwt
84 ```
85
86 You can use files or strings.
87
88 ```bash
89 keypairs verify \
90   '{ "crv": "P-256", "kty": "EC", "x": "5K5ALgtWw37KsZOrBdwCyGOGKCFd27u-t61dmUiieJY", "y": "wr3BNL-CeqkGtiRVqo3yizKxUA0bwS1MNZeqytdwICA" }' \
91   eyJhbGciOiJFUzI1NiIsImtpZCI6ImpkeHhZY1NCZUJfeUdoZWlCVW14NjF0eHExZGFjR1hIX191bEJuWlZHMEUiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjIxNDczODU3MTIsInN1YiI6Im1lQGV4YW1wbGUuY29tIn0.oh8-PUMdrbQU6seRXjo68wPWAKbA-V9LMnd_wZEkPHc3C8A5xJzV7mDDMNOLEy4VcuNGxced_yjYulzcMa5FLQ
92 ```
93
94 ### What do RSA and ECDSA JWKs look like?
95
96 `keypairs` will generate either ECDSA or RSA at random and only support
97 NIST-approved, industry-standard key types and options.
98
99 #### ECDSA Private
100
101 `[ "crv", "d", "kty", "x", "y" ]`
102
103 ```json
104 {
105   "crv": "P-256",
106   "d": "hYmoRZJp8b98wl0Daw49R1NjHfDhGNXP34-QyaCuZIk",
107   "kty": "EC",
108   "x": "5K5ALgtWw37KsZOrBdwCyGOGKCFd27u-t61dmUiieJY",
109   "y": "wr3BNL-CeqkGtiRVqo3yizKxUA0bwS1MNZeqytdwICA"
110 }
111 ```
112
113 #### ECDSA Public
114
115 `[ "crv", "kid", "kty", "use", "x", "y" ]`
116
117 ```json
118 {
119   "crv": "P-256",
120   "kid": "jdxxYcSBeB_yGheiBUmx61txq1dacGXH__ulBnZVG0E",
121   "kty": "EC",
122   "use": "sig",
123   "x": "5K5ALgtWw37KsZOrBdwCyGOGKCFd27u-t61dmUiieJY",
124   "y": "wr3BNL-CeqkGtiRVqo3yizKxUA0bwS1MNZeqytdwICA"
125 }
126 ```
127
128 Note that `kid` is the thumbprint, and `use` is omitted when generating
129 thumbprint.
130
131 #### RSA Private
132
133 `[ "d", "dp", "dq", "e", "kty", "n", "p", "q", "qi" ]`
134
135 ```json
136 {
137   "d": "cNTQBfVY_4zmQDZWUXILKVRldEwF6ujxQ08PGOSOczHQaoCdTVJtXlio7IZLbLLpG_doxgNr_VFtk64SaAgTs5fBA5SK8x-Xy44L8pl5c7Vlc7Am-fI5hTkWle79ZP5KygvXP34pgDMwQUqJfUEkJ8UwgW9ffO_OFJCBUnPwVG0PCfmGZi1usTtr0Kix31zOWPAdogVEMUoqRrrn_Maw8CUVUfr-k-xCo8pFTCJk3K5O7ZldZd9GotcdNUyL5_BsvD3iLIok6DFmZjt6Kfbf1Pu0yGw3deU9by8XQlG4zNW0ABdRYRGxbOn4ZTZYqiMqK2I47gv5RJkFeFfJKgdzAQ",
138   "dp": "WskCm6kAxywgOWBMHx8LtBUVqknK47pXHYa0tThyukclUS6NoGpm-rNAHQDyf_IF-237TzTmU5Qp3Oumybg8QvrmG7h3CbnxYplJdOvFFm3rtyUZ_rBAP-cXZYrqU3E8IArI3cKW1sXHS2S_9z8D0aI7jZ9IAJc29xSvSz9kFAk",
139   "dq": "W-R3Z-WVeEnHArVNvKlmjaHowemvQ67enefAkvrI3zQT537BxT1NS7cY27ehTl5x0dnywd-U3qObyYAGX34AMXyTLpKFwqkbd8zysZghAZPWtTUk09qYEwiC1cS3xl6D0Yyxg5KCFrLNQ33JY8CdDq0kY_JThUyAf6REcXSYokE",
140   "e": "AQAB",
141   "kty": "RSA",
142   "n": "vm0SbK4I_4LwXrLU6PR69Y331HJNXNCdPvlD4EZMUCqjQj-M6F7lopWeXBQy93H06s1LnLfdaE1-gRQv0ptzDNaupObi1SOeZiSmqaXJ3sQl0l01i4FXYvUboRrQWWsqkDwh1Azth7sf4m5nNfhqK_D4jfmtYoOAL-DsFXJ2018amcKBuiesOPXl4rw2BoHQoTXJq7YfWKpDWnm6s6zXLubTmHG9jv7NUKqoqCen6NJMSTP40uKA2LjEnkbxw2JwKm0KlBPuLvkrYECwpUGzqYboXfrulif9TS9p5nWXM1dLKN1rN91zqGZw_idXs6ebJW3x47J9Ta9dvD5wqsRh-Q",
143   "p": "yrDgavzG6bvvX4kpWbuvlWZZVXHkCS9zRlNbzEa-zqMmvfrckNc7b3VBAm8Id5-hgrHLnSOc7qG8t5xDPAKiNMXf2_ya-eLmCIAPwI5GzMNxFmKyvxUCN2z9lMASrwvxtV9dX4bIExZToN7NQqxAZwgn6BgMsmR_l7olo8nsUfU",
144   "q": "8IJn1cQaellOe0zi5zWF4QGzfARtu-6vKMvNkGRlB6gws3j6pIzd54IXa6O2H7tMjsK0jDXi3Wh4M1IdcGxJHT9aPt9UIdlgW1zbLhN-DfQku-i1_bQ4vMZ6_kchpZsDRbCIQ290ZfWSTaYp5EtBGM359W-jAH2v-IYtCuN6GXU",
145   "qi": "XFoxKvgujg1fwRsUiaKb7ptTxboGPWjcjivP67Hk-T28JfevJoyQQk2YmLqQLZZFr5uZ-POIIP2GQd-k2yXDyPsZXXe0-QTY4t0g2HXHInE4meROfnqfNjsijBrNqEQz_mqs9714tQXNdjpOExSUceh2DpepaS1z73gsqwTqeWI"
146 }
147 ```
148
149 #### RSA Public
150
151 `[ "e", "kid", "kty", "n", "use" ]`
152
153 ```json
154 {
155   "e": "AQAB",
156   "kid": "4GTGYg18yQLUndStAb65ZqPfDdWiBtYl4gzDZosSD38",
157   "kty": "RSA",
158   "n": "vm0SbK4I_4LwXrLU6PR69Y331HJNXNCdPvlD4EZMUCqjQj-M6F7lopWeXBQy93H06s1LnLfdaE1-gRQv0ptzDNaupObi1SOeZiSmqaXJ3sQl0l01i4FXYvUboRrQWWsqkDwh1Azth7sf4m5nNfhqK_D4jfmtYoOAL-DsFXJ2018amcKBuiesOPXl4rw2BoHQoTXJq7YfWKpDWnm6s6zXLubTmHG9jv7NUKqoqCen6NJMSTP40uKA2LjEnkbxw2JwKm0KlBPuLvkrYECwpUGzqYboXfrulif9TS9p5nWXM1dLKN1rN91zqGZw_idXs6ebJW3x47J9Ta9dvD5wqsRh-Q",
159   "use": "sig"
160 }
161 ```
162
163 Note that `kid` is the thumbprint, and `use` is omitted when generating
164 thumbprint.