Files
notfiles/crates/notsecrets/examples/age_smoke.rs

60 lines
1.8 KiB
Rust
Raw Normal View History

use notsecrets::{Decryptor, Encryptor, X25519Identity, X25519Recipient};
use rand::rngs::OsRng;
use x25519_dalek::{PublicKey, StaticSecret};
fn main() {
// 1. Generate a fresh keypair
let secret = StaticSecret::random_from_rng(OsRng);
let public = PublicKey::from(&secret);
let identity = X25519Identity::from_static_secret(secret);
let recipient = X25519Recipient::from_public_key(public);
println!("Recipient: {}", recipient.to_bech32());
println!("Identity: {}", identity.to_bech32());
// 2. Build plaintext from env
let plaintext = [
(
"ANTHROPIC_API_KEY",
std::env::var("ANTHROPIC_API_KEY").unwrap_or_default(),
),
(
"OPENAI_API_KEY",
std::env::var("OPENAI_API_KEY").unwrap_or_default(),
),
(
"GEMINI_API_KEY",
std::env::var("GEMINI_API_KEY").unwrap_or_default(),
),
]
.iter()
.map(|(k, v)| format!("{k}={v}"))
.collect::<Vec<_>>()
.join("\n");
let plaintext = plaintext.as_bytes();
// 3. Encrypt
let encryptor = Encryptor::with_recipients(vec![Box::new(recipient)]).unwrap();
let ciphertext = encryptor.encrypt(plaintext).unwrap();
println!("\nCiphertext: {} bytes", ciphertext.len());
println!(
"Header: {}",
std::str::from_utf8(&ciphertext[..22]).unwrap()
);
// 4. Write to file
let out_path = "/tmp/secrets.age";
std::fs::write(out_path, &ciphertext).unwrap();
println!("Written to: {out_path}");
// 5. Decrypt back
let decryptor = Decryptor::with_identities(vec![Box::new(identity)]);
let decrypted = decryptor.decrypt(&ciphertext).unwrap();
assert_eq!(decrypted, plaintext);
println!("\nDecrypted:\n{}", std::str::from_utf8(&decrypted).unwrap());
println!("\n✓ Round-trip success");
}