Add more tests and document SEC1 lack of support
This commit is contained in:
parent
6121db3d07
commit
d550c5f318
|
@ -132,6 +132,14 @@ You can use openssl for that:
|
||||||
openssl rsa -inform DER -outform PEM -in mykey.der -out mykey.pem
|
openssl rsa -inform DER -outform PEM -in mykey.der -out mykey.pem
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Convert SEC1 private key to PKCS8
|
||||||
|
`jsonwebtoken` currently only supports PKCS8 format for private EC keys. If your key has `BEGIN EC PRIVATE KEY` at the top,
|
||||||
|
this is a SEC1 type and can be converted to PKCS8 like so:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl pkcs8 -topk8 -nocrypt -in sec1.pem -out pkcs8.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
This library validates automatically the `exp` claim and `nbf` is validated if present. You can also validate the `sub`, `iss` and `aud` but
|
This library validates automatically the `exp` claim and `nbf` is validated if present. You can also validate the `sub`, `iss` and `aud` but
|
||||||
|
|
|
@ -13,7 +13,9 @@ enum PemType {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
enum Standard {
|
enum Standard {
|
||||||
|
// Only for RSA
|
||||||
Pkcs1,
|
Pkcs1,
|
||||||
|
// RSA/EC
|
||||||
Pkcs8,
|
Pkcs8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,23 +25,38 @@ pub struct Claims {
|
||||||
#[test]
|
#[test]
|
||||||
fn round_trip_sign_verification_pem() {
|
fn round_trip_sign_verification_pem() {
|
||||||
let privkey = include_bytes!("private_ecdsa_key.pem");
|
let privkey = include_bytes!("private_ecdsa_key.pem");
|
||||||
let encrypted = sign("hello world", privkey, Algorithm::ES256).unwrap();
|
|
||||||
let pubkey = include_bytes!("public_ecdsa_key.pem");
|
let pubkey = include_bytes!("public_ecdsa_key.pem");
|
||||||
|
let encrypted = sign("hello world", privkey, Algorithm::ES256).unwrap();
|
||||||
let is_valid = verify(&encrypted, "hello world", pubkey, Algorithm::ES256).unwrap();
|
let is_valid = verify(&encrypted, "hello world", pubkey, Algorithm::ES256).unwrap();
|
||||||
assert!(is_valid);
|
assert!(is_valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn round_trip_claim() {
|
fn round_trip_claim() {
|
||||||
|
let privkey = include_bytes!("private_ecdsa_key.pem");
|
||||||
|
let pubkey = include_bytes!("public_ecdsa_key.pem");
|
||||||
let my_claims = Claims {
|
let my_claims = Claims {
|
||||||
sub: "b@b.com".to_string(),
|
sub: "b@b.com".to_string(),
|
||||||
company: "ACME".to_string(),
|
company: "ACME".to_string(),
|
||||||
exp: Utc::now().timestamp() + 10000,
|
exp: Utc::now().timestamp() + 10000,
|
||||||
};
|
};
|
||||||
let privkey = include_bytes!("private_ecdsa_key.pem");
|
|
||||||
let token = encode(&Header::new(Algorithm::ES256), &my_claims, privkey).unwrap();
|
let token = encode(&Header::new(Algorithm::ES256), &my_claims, privkey).unwrap();
|
||||||
let pubkey = include_bytes!("public_ecdsa_key.pem");
|
|
||||||
let token_data = decode::<Claims>(&token, pubkey, &Validation::new(Algorithm::ES256)).unwrap();
|
let token_data = decode::<Claims>(&token, pubkey, &Validation::new(Algorithm::ES256)).unwrap();
|
||||||
assert_eq!(my_claims, token_data.claims);
|
assert_eq!(my_claims, token_data.claims);
|
||||||
assert!(token_data.header.kid.is_none());
|
}
|
||||||
|
|
||||||
|
// https://jwt.io/ is often used for examples so ensure their example works with jsonwebtoken
|
||||||
|
#[test]
|
||||||
|
fn roundtrip_with_jwtio_example() {
|
||||||
|
// We currently do not support SEC1 so we use the converted PKCS8 formatted
|
||||||
|
let privkey = include_bytes!("private_jwtio_pkcs8.pem");
|
||||||
|
let pubkey = include_bytes!("public_jwtio.pem");
|
||||||
|
let my_claims = Claims {
|
||||||
|
sub: "b@b.com".to_string(),
|
||||||
|
company: "ACME".to_string(),
|
||||||
|
exp: Utc::now().timestamp() + 10000,
|
||||||
|
};
|
||||||
|
let token = encode(&Header::new(Algorithm::ES384), &my_claims, privkey).unwrap();
|
||||||
|
let token_data = decode::<Claims>(&token, pubkey, &Validation::new(Algorithm::ES384)).unwrap();
|
||||||
|
assert_eq!(my_claims, token_data.claims);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
MIGkAgEBBDCAHpFQ62QnGCEvYh/pE9QmR1C9aLcDItRbslbmhen/h1tt8AyMhske
|
||||||
|
enT+rAyyPhGgBwYFK4EEACKhZANiAAQLW5ZJePZzMIPAxMtZXkEWbDF0zo9f2n4+
|
||||||
|
T1h/2sh/fviblc/VTyrv10GEtIi5qiOy85Pf1RRw8lE5IPUWpgu553SteKigiKLU
|
||||||
|
PeNpbqmYZUkWGh3MLfVzLmx85ii2vMU=
|
||||||
|
-----END EC PRIVATE KEY-----
|
|
@ -0,0 +1,6 @@
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCAHpFQ62QnGCEvYh/p
|
||||||
|
E9QmR1C9aLcDItRbslbmhen/h1tt8AyMhskeenT+rAyyPhGhZANiAAQLW5ZJePZz
|
||||||
|
MIPAxMtZXkEWbDF0zo9f2n4+T1h/2sh/fviblc/VTyrv10GEtIi5qiOy85Pf1RRw
|
||||||
|
8lE5IPUWpgu553SteKigiKLUPeNpbqmYZUkWGh3MLfVzLmx85ii2vMU=
|
||||||
|
-----END PRIVATE KEY-----
|
|
@ -0,0 +1,5 @@
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEC1uWSXj2czCDwMTLWV5BFmwxdM6PX9p+
|
||||||
|
Pk9Yf9rIf374m5XP1U8q79dBhLSIuaojsvOT39UUcPJROSD1FqYLued0rXiooIii
|
||||||
|
1D3jaW6pmGVJFhodzC31cy5sfOYotrzF
|
||||||
|
-----END PUBLIC KEY-----
|
|
@ -89,3 +89,22 @@ fn fails_with_non_pkcs8_key_format() {
|
||||||
let _encrypted =
|
let _encrypted =
|
||||||
sign("hello world", include_bytes!("private_rsa_key_pkcs1.pem"), Algorithm::ES256).unwrap();
|
sign("hello world", include_bytes!("private_rsa_key_pkcs1.pem"), Algorithm::ES256).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://jwt.io/ is often used for examples so ensure their example works with jsonwebtoken
|
||||||
|
#[test]
|
||||||
|
fn roundtrip_with_jwtio_example_jey() {
|
||||||
|
let privkey_pem = include_bytes!("private_jwtio.pem");
|
||||||
|
let pubkey_pem = include_bytes!("public_jwtio.pem");
|
||||||
|
|
||||||
|
let my_claims = Claims {
|
||||||
|
sub: "b@b.com".to_string(),
|
||||||
|
company: "ACME".to_string(),
|
||||||
|
exp: Utc::now().timestamp() + 10000,
|
||||||
|
};
|
||||||
|
|
||||||
|
for &alg in RSA_ALGORITHMS {
|
||||||
|
let token = encode(&Header::new(alg), &my_claims, privkey_pem).unwrap();
|
||||||
|
let token_data = decode::<Claims>(&token, pubkey_pem, &Validation::new(alg)).unwrap();
|
||||||
|
assert_eq!(my_claims, token_data.claims);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEogIBAAKCAQEAnzyis1ZjfNB0bBgKFMSvvkTtwlvBsaJq7S5wA+kzeVOVpVWw
|
||||||
|
kWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHcaT92whREFpLv9cj5lTeJSibyr/Mr
|
||||||
|
m/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIytvHWTxZYEcXLgAXFuUuaS3uF9gEi
|
||||||
|
NQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0e+lf4s4OxQawWD79J9/5d3Ry0vbV
|
||||||
|
3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWbV6L11BWkpzGXSW4Hv43qa+GSYOD2
|
||||||
|
QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9MwIDAQABAoIBACiARq2wkltjtcjs
|
||||||
|
kFvZ7w1JAORHbEufEO1Eu27zOIlqbgyAcAl7q+/1bip4Z/x1IVES84/yTaM8p0go
|
||||||
|
amMhvgry/mS8vNi1BN2SAZEnb/7xSxbflb70bX9RHLJqKnp5GZe2jexw+wyXlwaM
|
||||||
|
+bclUCrh9e1ltH7IvUrRrQnFJfh+is1fRon9Co9Li0GwoN0x0byrrngU8Ak3Y6D9
|
||||||
|
D8GjQA4Elm94ST3izJv8iCOLSDBmzsPsXfcCUZfmTfZ5DbUDMbMxRnSo3nQeoKGC
|
||||||
|
0Lj9FkWcfmLcpGlSXTO+Ww1L7EGq+PT3NtRae1FZPwjddQ1/4V905kyQFLamAA5Y
|
||||||
|
lSpE2wkCgYEAy1OPLQcZt4NQnQzPz2SBJqQN2P5u3vXl+zNVKP8w4eBv0vWuJJF+
|
||||||
|
hkGNnSxXQrTkvDOIUddSKOzHHgSg4nY6K02ecyT0PPm/UZvtRpWrnBjcEVtHEJNp
|
||||||
|
bU9pLD5iZ0J9sbzPU/LxPmuAP2Bs8JmTn6aFRspFrP7W0s1Nmk2jsm0CgYEAyH0X
|
||||||
|
+jpoqxj4efZfkUrg5GbSEhf+dZglf0tTOA5bVg8IYwtmNk/pniLG/zI7c+GlTc9B
|
||||||
|
BwfMr59EzBq/eFMI7+LgXaVUsM/sS4Ry+yeK6SJx/otIMWtDfqxsLD8CPMCRvecC
|
||||||
|
2Pip4uSgrl0MOebl9XKp57GoaUWRWRHqwV4Y6h8CgYAZhI4mh4qZtnhKjY4TKDjx
|
||||||
|
QYufXSdLAi9v3FxmvchDwOgn4L+PRVdMwDNms2bsL0m5uPn104EzM6w1vzz1zwKz
|
||||||
|
5pTpPI0OjgWN13Tq8+PKvm/4Ga2MjgOgPWQkslulO/oMcXbPwWC3hcRdr9tcQtn9
|
||||||
|
Imf9n2spL/6EDFId+Hp/7QKBgAqlWdiXsWckdE1Fn91/NGHsc8syKvjjk1onDcw0
|
||||||
|
NvVi5vcba9oGdElJX3e9mxqUKMrw7msJJv1MX8LWyMQC5L6YNYHDfbPF1q5L4i8j
|
||||||
|
8mRex97UVokJQRRA452V2vCO6S5ETgpnad36de3MUxHgCOX3qL382Qx9/THVmbma
|
||||||
|
3YfRAoGAUxL/Eu5yvMK8SAt/dJK6FedngcM3JEFNplmtLYVLWhkIlNRGDwkg3I5K
|
||||||
|
y18Ae9n7dHVueyslrb6weq7dTkYDi3iOYRW8HRkIQh06wEdbxt0shTzAJvvCQfrB
|
||||||
|
jg/3747WSsf/zBTcHihTRBdAv6OmdhV4/dD5YBfLAkLrd+mX7iE=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,9 @@
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSv
|
||||||
|
vkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHc
|
||||||
|
aT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIy
|
||||||
|
tvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0
|
||||||
|
e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWb
|
||||||
|
V6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9
|
||||||
|
MwIDAQAB
|
||||||
|
-----END PUBLIC KEY-----
|
Loading…
Reference in New Issue