This is a guide to using pyjwt
to sign and validate a JWT
using
RS256.
The trickiest part of doing this is knowing what the proper OpenSSL commands are to generate the RSA keypair. I demonstrate that below.
Here is how use the OpenSSL command line tool to generate a private key with a size of 1024.
openssl genrsa 1024
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCxlVm+DawmijNIDmAt11Sk5lRkd9691RyQevmr8u/eKvTV7eta
ZmGm2GmbuURYzwQfQ1+DFNrzu70wBLTyDrxCoX/vb/5hANwLJr5Eec6gGTF6/y4F
riRM1NEBZG9PnvmEPa1bfa27dnV5hz+GTIsCFCw4rXGI7c6ETg+v9t4HqQIDAQAB
AoGAMoekuYd6bJz2apJsm56h3yoK6WuSXcG+Fv5m/J5r0nO2pwjD5z0qnCcIJd9Z
q0t8iMjK7KmKg7/v3TH5qsa2mmUZ8UYMI5VmkwlKL4BD9mT67+ZAlqdLOHlrdrhG
u2FWR0PF5W2z06NqohWHepL01K7PLtxzaVzbQIwS4X3YsuECQQDrcqdSqj6gSF3Q
ZOZEMoES64iwAe/Fi4VmE6s0PEhoVXbbxFNxuvQPkylmoGs82ByAqltNk7p8G0Wb
hd+j3/KHAkEAwRWmkD189gSR/jLPEy/2fIkXhfe98OruPyG2yDsa3vp5wC2nrniG
udMxC4OJ1yXHGt4KBeOoOL94lX9p9UhQTwJAOx+SZs67ZTJm5HLB4/Qut1qP+2qx
FBEiEWz0++v7Xr+/VhZpwdBpgxO4PL4hz6iRF7ovrT5ggNO0WgZ3D0aoNwJBAKhx
T9ajnaEuCYLeJmJRxFGOc3QO1agX+3Id4kw5q858arxp18/QG5B/Glk2Dokfztu0
er/6hCXFe9fHyNMPm+cCQQCsqdhniYyaHPlyn/6bOwCcZua74JRZ3vNSkjAKzHan
WjSRdVvCHs8bY1Um0QZ+nHpT3QhcBPYyQoJArs8P1XBH
-----END RSA PRIVATE KEY-----
Now that we have this private key, let's take a look at what's inside and then extract the public key into a separate string.
Here is what is inside the keypair we just generated:
(Note: The sed
command below is needed because org-babel adds
leading whitespace to the string and OpenSSL can't deal keypairs
that have leading whitespace.
echo "$private_key" | sed -e 's/^[ ]*//' | openssl rsa -text
Private-Key: (1024 bit)
modulus:
00:aa:ad:9a:f3:09:8d:68:4c:44:09:5b:ab:d4:27:
7a:7d:0e:00:66:dc:e0:67:58:62:1e:78:d1:2a:7e:
de:b0:a2:24:b2:9b:03:5d:1f:17:d0:b1:9a:df:2c:
e7:e7:c3:17:56:90:f2:07:91:84:ec:84:76:10:43:
35:97:6d:af:03:e7:bf:0e:e3:53:8f:26:10:be:8e:
e2:12:ae:56:2d:34:14:0a:ae:ef:e7:01:3d:4d:7c:
f7:1e:c8:11:ca:6f:6f:cf:b7:67:e2:ac:54:77:20:
09:89:14:c0:66:21:cd:77:fa:91:25:66:59:31:c2:
c5:59:fe:0e:99:83:f0:56:b3
publicExponent: 65537 (0x10001)
privateExponent:
4d:57:b2:39:a4:00:82:5c:dd:0f:e8:8c:aa:ec:e0:
e2:be:6f:8c:2d:57:3b:3d:9f:e8:f3:12:c5:d1:0c:
14:ba:c5:2a:72:78:49:c0:87:48:38:d3:57:82:bf:
ec:14:4a:05:1e:55:ae:fc:50:61:e5:7c:a2:cd:f2:
01:16:e1:11:84:19:61:58:5f:fb:69:8d:ff:76:64:
fc:e8:3a:b9:28:84:9f:35:d8:9f:96:5c:c8:73:7d:
39:76:7c:99:a4:81:0d:50:c0:f0:51:45:9d:76:7a:
f4:53:81:0f:dd:3f:98:40:9b:a0:c5:cc:71:98:f3:
38:10:1b:b8:42:ff:4b:21
prime1:
00:df:89:a7:0c:cb:d0:8e:81:76:2a:a0:e0:83:ae:
70:69:4e:8b:ec:f2:ce:57:9b:16:d5:9a:72:be:66:
e4:b8:1a:84:e7:f4:28:2e:d6:70:50:f0:0f:85:ed:
67:33:d2:30:a2:2b:23:da:85:81:7c:2e:85:80:7f:
4d:74:a9:95:69
prime2:
00:c3:76:d1:de:11:ed:3b:16:97:ad:0e:65:22:ad:
1a:bd:95:a7:e7:f8:65:07:3e:ad:bf:30:d6:d4:9a:
04:9e:4b:5d:08:f2:2d:1e:5c:81:5a:04:80:f7:9d:
92:e6:54:e1:62:89:67:d1:f3:1a:ff:77:5b:a0:06:
5a:d8:79:3b:bb
exponent1:
16:2c:8c:72:9b:81:2b:b1:b1:ec:16:9b:4e:d4:ad:
f7:f4:3f:b3:18:7e:d9:77:db:f3:02:68:21:75:09:
79:2d:c0:43:56:17:ea:55:81:3c:b6:23:84:10:81:
ad:45:4b:67:ba:c9:ca:b2:75:9e:c0:ea:a3:4d:7d:
7c:76:1a:09
exponent2:
2f:ac:1b:23:7e:5b:cd:bd:84:e0:c0:52:0a:53:0d:
e2:8f:4d:94:56:10:cd:e3:8b:9c:c5:dc:9f:9d:b0:
e2:aa:9e:d6:3f:ba:a1:5d:0e:6f:56:09:de:5a:a0:
29:6d:2a:4b:4e:17:f4:2c:c6:b8:e7:f3:80:e4:0b:
e4:20:2d:61
coefficient:
00:c6:4d:e9:e0:56:90:c7:a1:c0:c9:72:c0:bd:17:
93:e8:fc:5a:64:5c:76:e2:74:67:e1:9d:3e:48:55:
bb:d2:c0:30:23:4e:21:5a:a8:01:52:11:53:f3:e2:
d4:61:2e:38:8c:18:b2:2e:87:02:c3:4d:b3:c8:64:
dd:50:39:33:06
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqrZrzCY1oTEQJW6vUJ3p9DgBm3OBnWGIeeNEqft6woiSymwNd
HxfQsZrfLOfnwxdWkPIHkYTshHYQQzWXba8D578O41OPJhC+juISrlYtNBQKru/n
AT1NfPceyBHKb2/Pt2firFR3IAmJFMBmIc13+pElZlkxwsVZ/g6Zg/BWswIDAQAB
AoGATVeyOaQAglzdD+iMquzg4r5vjC1XOz2f6PMSxdEMFLrFKnJ4ScCHSDjTV4K/
7BRKBR5VrvxQYeV8os3yARbhEYQZYVhf+2mN/3Zk/Og6uSiEnzXYn5ZcyHN9OXZ8
maSBDVDA8FFFnXZ69FOBD90/mECboMXMcZjzOBAbuEL/SyECQQDfiacMy9COgXYq
oOCDrnBpTovs8s5XmxbVmnK+ZuS4GoTn9Cgu1nBQ8A+F7Wcz0jCiKyPahYF8LoWA
f010qZVpAkEAw3bR3hHtOxaXrQ5lIq0avZWn5/hlBz6tvzDW1JoEnktdCPItHlyB
WgSA952S5lThYoln0fMa/3dboAZa2Hk7uwJAFiyMcpuBK7Gx7BabTtSt9/Q/sxh+
2Xfb8wJoIXUJeS3AQ1YX6lWBPLYjhBCBrUVLZ7rJyrJ1nsDqo019fHYaCQJAL6wb
I35bzb2E4MBSClMN4o9NlFYQzeOLnMXcn52w4qqe1j+6oV0Ob1YJ3lqgKW0qS04X
9CzGuOfzgOQL5CAtYQJBAMZN6eBWkMehwMlywL0Xk+j8WmRcduJ0Z+GdPkhVu9LA
MCNOIVqoAVIRU/Pi1GEuOIwYsi6HAsNNs8hk3VA5MwY=
-----END RSA PRIVATE KEY-----
Here we use the -pubout
flag to extract the public key that we
will use later.
echo "$private_key" | sed -e 's/^[ ]*//' | openssl rsa -pubout
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqrZrzCY1oTEQJW6vUJ3p9DgBm
3OBnWGIeeNEqft6woiSymwNdHxfQsZrfLOfnwxdWkPIHkYTshHYQQzWXba8D578O
41OPJhC+juISrlYtNBQKru/nAT1NfPceyBHKb2/Pt2firFR3IAmJFMBmIc13+pEl
ZlkxwsVZ/g6Zg/BWswIDAQAB
-----END PUBLIC KEY-----
This is a little Python list comprehension that will strip out leading whitespace from input key:
key = "\n".join([l.lstrip() for l in input_key.split("\n")])
And here we take the private_key
we created with OpenSSL and use
that to create a JWT that is signed with RS256:
key = "\n".join([l.lstrip() for l in input_key.split("\n")])
claim = {'test': "hello"}
import jwt
token = jwt.encode(
claim,
key,
algorithm='RS256')
return token
Now, taking that result, we can decode the JWT we just generated and verify the signature:
key = "\n".join([l.lstrip() for l in input_key.split("\n")])
import jwt
return jwt.decode(token, key, algorithms=['RS256'])
{u'test': u'hello'}
@rayluo yes then are different keys, the name(identifier) of the variable doesn't matter.
Only thing to keep in mind is you use private key to encrypt data and public key to decypt data.