Skip to content

Instantly share code, notes, and snippets.

@wranders
Last active July 26, 2023 22:57
Show Gist options
  • Save wranders/9693d9d5be87931d9d7050cb856a50f1 to your computer and use it in GitHub Desktop.
Save wranders/9693d9d5be87931d9d7050cb856a50f1 to your computer and use it in GitHub Desktop.
Generate EC and RSA key pairs using rust-openssl
use openssl::bn::BigNumContext;
use openssl::ec::{EcGroup,EcKey,EcPoint,PointConversionForm};
use openssl::nid::Nid;
use openssl::pkey::{Private,Public};
use openssl::rsa::Rsa;
use openssl::symm::Cipher;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// private key passphrase
const PASSPHRASE: &[u8] = "some passphrase".as_bytes();
// private key cipher
let cipher: Cipher = Cipher::aes_256_cbc();
// generate EC key pair
let (ec_private, ec_public) = ec_key_pair(Nid::SECP384R1)?;
// encrypt EC private key with passphrase using specified cipher
let ec_private_pem_enc: Vec<u8> = ec_private.private_key_to_pem_passphrase(cipher, PASSPHRASE)?;
// convert public key to PEM
let ec_public_pem: Vec<u8> = ec_public.public_key_to_pem()?;
println!(
"+++++EC+++++\n{}\n{}",
std::str::from_utf8(&ec_private_pem_enc).unwrap(),
std::str::from_utf8(&ec_public_pem).unwrap(),
);
// generate RSA key pair
let (rsa_private, rsa_public) = rsa_key_pair(2048)?;
// encrypt RSA private key with passphrase using specified cipher
let rsa_private_pem_enc: Vec<u8> = rsa_private.private_key_to_pem_passphrase(cipher, PASSPHRASE)?;
// convert public key to PEM
let rsa_public_pem: Vec<u8> = rsa_public.public_key_to_pem()?;
println!(
"+++++RSA+++++\n{}\n{}",
std::str::from_utf8(&rsa_private_pem_enc).unwrap(),
std::str::from_utf8(&rsa_public_pem).unwrap(),
);
Ok(())
}
/// Generate EC Key Pair
fn ec_key_pair(nid: Nid) -> Result<(EcKey<Private>, EcKey<Public>), Box<dyn std::error::Error>> {
let group: EcGroup = match EcGroup::from_curve_name(nid) {
Ok(group) => group,
Err(err) => return Err(err.into()),
};
let private_key: EcKey<Private> = EcKey::generate(&group)?;
let mut ctx: BigNumContext = BigNumContext::new()?;
let form: PointConversionForm = PointConversionForm::COMPRESSED;
let buf: Vec<u8> = private_key.public_key().to_bytes(&group, form, &mut ctx)?;
let point: EcPoint = EcPoint::from_bytes(&group, &buf, &mut ctx)?;
let public_key: EcKey<Public> = EcKey::from_public_key(&group, &point)?;
Ok((private_key, public_key))
}
/// Generate RSA Key Pair
fn rsa_key_pair(bits: u32) -> Result<(Rsa<Private>, Rsa<Public>), Box<dyn std::error::Error>> {
let private_key: Rsa<Private> = Rsa::generate(bits)?;
let public_key_pem: Vec<u8> = private_key.public_key_to_pem()?;
let public_key: Rsa<Public> = Rsa::public_key_from_pem(&public_key_pem)?;
Ok((private_key, public_key))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment