josekit

JOSE (Javascript Object Signing and Encryption: JWT, JWS, JWE, JWA, JWK) library for Rust.

Notice: This package doesn't support JWE yet.

Install

toml [dependencies] josekit = "0.3.0"

This library depends on OpenSSL DLL. Read more about Crate openssl.

Build

sh sudo apt install build-essential pkg-config libssl-dev cd josekit-rs cargo build --release

Supported signature algorithms

|Name |Description |Curve | |------|----------------------------------------------|--------------| |HS256 |HMAC using SHA-256 | | |HS384 |HMAC using SHA-384 | | |HS512 |HMAC using SHA-512 | | |RS256 |RSASSA-PKCS1-v15 using SHA-256 | | |RS384 |RSASSA-PKCS1-v15 using SHA-384 | | |RS512 |RSASSA-PKCS1-v1_5 using SHA-512 | | |PS256 |RSASSA-PSS using SHA-256 and MGF1 with SHA-256| | |PS384 |RSASSA-PSS using SHA-384 and MGF1 with SHA-384| | |PS512 |RSASSA-PSS using SHA-512 and MGF1 with SHA-512| | |ES256 |ECDSA using P-256 and SHA-256 | | |ES384 |ECDSA using P-384 and SHA-384 | | |ES512 |ECDSA using P-521 and SHA-512 | | |ES256K|ECDSA using secp256k1 curve and SHA-256 | | |EdDSA |EdDSA signature algorithms |Ed25519, Ed448| |None |No digital signature or MAC performed | |

Supported key formats for RSA/RSA-PSS/ECDSA/EdDSA sigining

Algorithm JWK PEM DER
PKCS#8 Traditional PKCS#8 Raw
RSA OK OK OK OK OK
RSA-PSS OK OK OK OK -
ECDSA OK OK OK OK OK
EdDSA OK OK OK OK -

Usage

Signing a JWT by HMAC

HMAC is used to verify the integrity of a message by common secret key. Three types of HMAC algorithms are available: HS256, HS384, and HS512. You can use any text as the key.

```rust use josekit::jws::{ JwsHeader, HS256 }; use josekit::jwt::{ self, JwtPayload };

let mut header = JwsHeader::new(); header.settokentype("JWT");

let mut payload = JwtPayload::new(); payload.set_subject("subject");

let commonsecretkey = b"secret";

// Signing JWT let signer = HS256.signerfrombytes(privatekey)?; let jwt = jwt::encodewith_signer(&payload, &header, &signer)?;

// Verifing JWT let verifier = HS256.signerfrombytes(privatekey)? let (payload, header) = jwt::decodewith_verifier(&jwt, &verifier)?; ```

Signing a JWT by RSA

RSA is used to verify the integrity of a message by two keys: public and private. Three types of RSA algorithms are available: RS256, RS384, and RS512.

You can generate the keys by executing openssl command.

```sh

Generate a new private key. Keygen bits must be 2048 or more.

openssl openssl genpkey -algorithm RSA -pkeyopt rsakeygenbits:2048 -out RSA_private.pem

Generate a public key from the private key.

openssl pkey -in RSAprivate.pem -pubout -outform PEM -out RSApublic.pem ```

```rust use josekit::jws::{ JwsHeader, RS256 }; use josekit::jwt::{ self, JwtPayload };

let mut header = JwsHeader::new(); header.settokentype("JWT");

let mut payload = JwtPayload::new(); payload.set_subject("subject");

// Signing JWT let privatekey = loadfromfile("rsaprivate.pem")?; let signer = RS256.signerfrompem(&privatekey)?; let jwt = jwt::encodewith_signer(&payload, &header, &signer)?;

// Verifing JWT let publickey = loadfromfile("rsapublic.pem")?; let verifier = RS256.verifierfrompem(&publickey)?; let (payload, header) = jwt::decodewith_verifier(&jwt, &verifier)?; ```

Signing a JWT by RSA-PSS

RSA-PSS is used to verify the integrity of a message by two keys: public and private.

The raw key format of RSA-PSS is the same as RSA. So you should use a PKCS#8 wrapped key. It contains some optional attributes.

Three types of RSA-PSS algorithms are available: PS256, PS384, and PS512. You can generate the keys by executing openssl command.

```sh

Generate a new private key

for PS256

openssl genpkey -algorithm RSA-PSS -pkeyopt rsakeygenbits:2048 -pkeyopt rsapsskeygenmd:sha256 -pkeyopt rsapsskeygenmgf1md:sha256 -pkeyopt rsapsskeygensaltlen:32 -out RSA-PSS_private.pem

for PS384

openssl genpkey -algorithm RSA-PSS -pkeyopt rsakeygenbits:2048 -pkeyopt rsapsskeygenmd:sha384 -pkeyopt rsapsskeygenmgf1md:sha384 -pkeyopt rsapsskeygensaltlen:48 -out RSA-PSS_private.pem

for PS512

openssl genpkey -algorithm RSA-PSS -pkeyopt rsakeygenbits:2048 -pkeyopt rsapsskeygenmd:sha512 -pkeyopt rsapsskeygenmgf1md:sha512 -pkeyopt rsapsskeygensaltlen:64 -out RSA-PSS_private.pem

Generate a public key from the private key.

openssl pkey -in RSA-PSSprivate.pem -pubout -outform PEM -out RSA-PSSpublic.pem ```

```rust use josekit::jws::{ JwsHeader, PS256 }; use josekit::jwt::{ self, JwtPayload };

let mut header = JwsHeader::new(); header.settokentype("JWT");

let mut payload = JwtPayload::new(); payload.set_subject("subject");

// Signing JWT let privatekey = loadfromfile("rsapssprivate.pem")?; let signer = PS256.signerfrompem(&privatekey)?; let jwt = jwt::encodewith_signer(&payload, &header, &signer)?;

// Verifing JWT let publickey = loadfromfile("rsapsspublic.pem")?; let verifier = PS256.verifierfrompem(&publickey)?; let (payload, header) = jwt::decodewith_verifier(&jwt, &verifier)?; ```

Signing a JWT by ECDSA

ECDSA is used to verify the integrity of a message by two keys: public and private. Four types of ECDSA algorithms are available: ES256, ES384, ES512 and ES256K.

You can generate the keys by executing openssl command.

```sh

Generate a new private key

for ES256

openssl genpkey -algorithm EC -pkeyopt ecparamgencurve:P-256 -outform PEM -out ECDSA_private.pem

for ES384

openssl genpkey -algorithm EC -pkeyopt ecparamgencurve:P-384 -outform PEM -out ECDSA_private.pem

for ES512

openssl genpkey -algorithm EC -pkeyopt ecparamgencurve:P-521 -outform PEM -out ECDSA_private.pem

for ES256K

openssl genpkey -algorithm EC -pkeyopt ecparamgencurve:secp256k1 -outform PEM -out ECDSA_private.pem

Generate a public key from the private key.

openssl pkey -in ECDSAprivate.pem -pubout -outform PEM -out ECDSApublic.pem ```

```rust use josekit::jws::{ JwsHeader, ES256 }; use josekit::jwt::{ self, JwtPayload };

let mut header = JwsHeader::new(); header.settokentype("JWT");

let mut payload = JwtPayload::new(); payload.set_subject("subject");

// Signing JWT let privatekey = loadfromfile("ECDSAprivate.pem")?; let signer = ES256.signerfrompem(&privatekey)?; let jwt = jwt::encodewith_signer(&payload, &header, &signer)?;

// Verifing JWT let publickey = loadfromfile("ECDSApublic.pem")?; let verifier = ES256.verifierfrompem(&publickey)?; let (payload, header) = jwt::decodewith_verifier(&jwt, &verifier)?; ```

Signing a JWT by EdDSA

EdDSA is used to verify the integrity of a message by two keys: public and private. Types of EdDSA algorithms is only "EdDSA". But it has two curve types: ED25519, ED448.

You can generate the keys by executing openssl command.

```sh

Generate a new private key

for ED25519

openssl genpkey -algorithm ED25519 -out ED25519_private.pem

for ED448

openssl genpkey -algorithm ED448 -out ED448_private.pem

Generate a public key from the private key.

openssl pkey -in ECDSAprivate.pem -pubout -outform PEM -out ECDSApublic.pem ```

```rust use josekit::jws::{ JwsHeader, EdDSA }; use josekit::jwt::{ self, JwtPayload };

let mut header = JwsHeader::new(); header.settokentype("JWT");

let mut payload = JwtPayload::new(); payload.set_subject("subject");

// Signing JWT let privatekey = loadfromfile("EdDSAprivate.pem")?; let signer = EdDSA.signerfrompem(&privatekey)?; let jwt = jwt::encodewith_signer(&payload, &header, &signer)?;

// Verifing JWT let publickey = loadfromfile("EdDSApublic.pem")?; let verifier = EdDSA.verifierfrompem(&publickey)?; let (payload, header) = jwt::decodewith_verifier(&jwt, &verifier)?; ```

Encrypted JWT

Not support yet.

Unsecured JWT

```rust use josekit::jws::JwsHeader; use josekit::jwt::{self, JwtPayload};

let mut header = JwsHeader::new(); header.settokentype("JWT");

let mut payload = JwtPayload::new(); payload.set_subject("subject");

let jwt = jwt::encodeunsecured(&payload, &header)?; let (payload, header) = jwt::decodeunsecured(&jwt)?; ```

Validate payload

```rust use josekit::jwt::{self, JwtPayloadValidator };

... let (payload, ) = jwt::decodewith_verifier(&jwt, &verifier)?;

let mut validator = JwtPayloadValidator::new(); // value based validation validator.setissuer("http://example.com"); validator.setaudience("user1"); validator.setjwtid("550e8400-e29b-41d4-a716-446655440000");

// time based validation: notbefore <= basetime < expiresat validator.setbasetime(SystemTime::now() + Duration::fromsecs(30));

// issued time based validation: minissuedtime <= issuedtime <= maxissuedtime validator.setminissuedtime(SystemTime::now() - Duration::fromsecs(48 * 60)); validator.setmaxissuedtime(SystemTime::now() + Duration::from_secs(24 * 60));

validator.validate(&payload)?; ```

ToDo

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

References