Skip to content

Instantly share code, notes, and snippets.

@maxpowel
Created October 25, 2022 11:50
Show Gist options
  • Save maxpowel/fe65023f496c455f34d329626c7a362d to your computer and use it in GitHub Desktop.
Save maxpowel/fe65023f496c455f34d329626c7a362d to your computer and use it in GitHub Desktop.
Example of encrypt and decrypt AES using ring ilbrary
/// Deps:
/// ring = "0.16.20"
/// base64 = "0.13.1"
/// Rust version 1.64.0
use ring::aead::{AES_256_GCM, UnboundKey};
use base64::{encode, decode};
use ring::{aead, error, rand};
struct OneNonceSequence(Option<aead::Nonce>);
impl OneNonceSequence {
fn new(nonce: aead::Nonce) -> Self {
Self(Some(nonce))
}
}
impl aead::NonceSequence for OneNonceSequence {
fn advance(&mut self) -> Result<aead::Nonce, error::Unspecified> {
self.0.take().ok_or(error::Unspecified)
}
}
fn encrypt(message: &str, key:&[u8], nonce:&[u8]) -> String {
let mut sealing_key = {
let key = UnboundKey::new(&AES_256_GCM, key).unwrap();
let nonce = OneNonceSequence::new(aead::Nonce::try_assume_unique_for_key(nonce).unwrap());
let a: aead::SealingKey<OneNonceSequence> = aead::BoundKey::new(key, nonce);
a
};
let aad = b"";
let aad = aead::Aad::from(&aad[..]);
let mut in_out: Vec<u8> = message.as_bytes().to_vec();
sealing_key.seal_in_place_append_tag(aad, &mut in_out).unwrap();
encode(&in_out)
}
fn decrypt(message: &str, key:&[u8], nonce:&[u8]) -> String {
let mut opening_key = {
let key = UnboundKey::new(&AES_256_GCM, key).unwrap();
let nonce = OneNonceSequence::new(aead::Nonce::try_assume_unique_for_key(nonce).unwrap());
let a: aead::OpeningKey<OneNonceSequence> = aead::BoundKey::new(key, nonce);
a
};
let mut in_out = decode(message).unwrap().to_vec();
let aad = b"";
let aad = aead::Aad::from(&aad[..]);
let data = opening_key.open_in_place(aad, &mut in_out).unwrap();
std::str::from_utf8(data).unwrap().to_owned()
}
fn main() {
let key = b"12a97d88d634afdf9f4da5bd35223f01";
let original_message = "Hi this is a test";
println!("Original message: {original_message}");
let rng = rand::SystemRandom::new();
let random_data: rand::Random<[u8;16]> = rand::generate(&rng).unwrap();
// Cannot generate 12 bytes directly so I generate 16 and get only the 12 first bytes
let nonce = &random_data.expose()[..12];
// Encrypt the message en encode64 it to make it text readable
let data = encrypt(original_message, key, nonce);
println!("Encoded message: {data}");
// Now the reverse way
let received_message = decrypt(&data, key, nonce);
println!("Received message: {received_message}");
println!("Success: {}", received_message == original_message);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment