Created
March 28, 2017 17:19
-
-
Save et4te/780a37b8dcd67d98a181e4860b47cbf6 to your computer and use it in GitHub Desktop.
JWK Rust Simple RSA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[macro_use] extern crate serde_derive; | |
extern crate rustc_serialize; | |
extern crate openssl; | |
extern crate dotenv; | |
extern crate serde; | |
extern crate serde_json; | |
use rustc_serialize::base64::{self, ToBase64}; | |
use std::path::Path; | |
use openssl::rsa::Rsa; | |
use openssl::bn::BigNumRef; | |
use openssl::types::{OpenSslType, OpenSslTypeRef}; | |
use dotenv::dotenv; | |
use std::env; | |
// Utility to convert BigNumRefs to base64 | |
fn bn_to_base64(bn: &BigNumRef) -> String { | |
bn.to_vec().to_base64(base64::URL_SAFE) | |
} | |
#[derive(Serialize, Deserialize)] | |
struct SecretKey { | |
pub kty: String, | |
pub n: String, | |
pub e: String, | |
pub d: String, | |
pub p: String, | |
pub q: String, | |
pub dp: String, | |
pub dq: String, | |
pub qi: String, | |
} | |
#[derive(Serialize, Deserialize)] | |
struct PublicKey { | |
pub kid: String, | |
pub kty: String, | |
pub n: String, | |
pub e: String, | |
} | |
// Using a path from the config generates JWKs | |
fn main() { | |
dotenv().ok(); | |
let public_key_path: String = env::var("PUBLIC_KEY_PATH") | |
.expect("PUBLIC_KEY_PATH required"); | |
let secret_key_path: String = env::var("SECRET_KEY_PATH") | |
.expect("SECRET_KEY_PATH required"); | |
let public_key_path = Path::new(public_key_path.as_str()).join("public-key.json"); | |
let secret_key_path = Path::new(secret_key_path.as_str()).join("secret-key.json"); | |
println!("Running generate_keys ..."); | |
println!("PUBLIC_KEY_PATH = {:?}", public_key_path.clone()); | |
println!("SECRET_KEY_PATH = {:?}", secret_key_path.clone()); | |
if secret_key_path.exists() { | |
println!("A secret key has already been generated for this service.") | |
} else { | |
let rsa = Rsa::generate(2048).unwrap(); | |
let n = rsa.n().unwrap(); | |
let d = rsa.d().unwrap(); | |
let e = rsa.e().unwrap(); | |
let p = rsa.p().unwrap(); | |
let q = rsa.q().unwrap(); | |
// get (dp, dq, qi) | |
unsafe { | |
let rsa_ptr = rsa.as_ptr(); | |
if rsa_ptr.is_null() { | |
println!("Error, RSA pointer was null"); | |
} else { | |
let dp = BigNumRef::from_ptr((*rsa_ptr).dmp1); | |
let dq = BigNumRef::from_ptr((*rsa_ptr).dmq1); | |
let qi = BigNumRef::from_ptr((*rsa_ptr).iqmp); | |
let secret_key = SecretKey { | |
kty: "RSA".to_string(), | |
n: bn_to_base64(n.clone()), | |
d: bn_to_base64(d), | |
e: bn_to_base64(e.clone()), | |
p: bn_to_base64(p), | |
q: bn_to_base64(q), | |
dp: bn_to_base64(dp), | |
dq: bn_to_base64(dq), | |
qi: bn_to_base64(qi), | |
}; | |
let public_key = PublicKey { | |
kid: "dev-1".to_string(), | |
kty: "RSA".to_string(), | |
n: bn_to_base64(n), | |
e: bn_to_base64(e), | |
}; | |
let secret_key_json = serde_json::to_string(&secret_key).unwrap(); | |
let public_key_json = serde_json::to_string(&public_key).unwrap(); | |
println!("Generated secret key = {}", secret_key_json); | |
println!("Generated public key = {}", public_key_json); | |
println!("Success"); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment