Skip to main content

secure_env/
crypto.rs

1use age::secrecy::SecretString;
2use age::{Decryptor, Encryptor};
3use anyhow::{Context, Result};
4use std::io::{Read, Write};
5
6/// Encrypt `plain` with `passphrase` using age (scrypt + ChaCha20-Poly1305).
7pub fn encrypt(plain: &[u8], passphrase: SecretString) -> Result<Vec<u8>> {
8    let encryptor = Encryptor::with_user_passphrase(passphrase);
9    let mut ciphertext = Vec::new();
10    let mut writer = encryptor
11        .wrap_output(&mut ciphertext)
12        .context("failed to create age encryptor")?;
13    writer
14        .write_all(plain)
15        .context("failed to encrypt data")?;
16    writer
17        .finish()
18        .context("failed to finalize age encryption")?;
19    Ok(ciphertext)
20}
21
22/// Decrypt `ciphertext` with `passphrase`, returning the plaintext bytes.
23pub fn decrypt(ciphertext: &[u8], passphrase: SecretString) -> Result<Vec<u8>> {
24    let decryptor = Decryptor::new(ciphertext).context("invalid age ciphertext")?;
25    let identity = age::scrypt::Identity::new(passphrase);
26    let mut reader = decryptor
27        .decrypt(std::iter::once(&identity as &dyn age::Identity))
28        .context("failed to decrypt (wrong passphrase?)")?;
29    let mut plaintext = Vec::new();
30    reader
31        .read_to_end(&mut plaintext)
32        .context("failed to read decrypted data")?;
33    Ok(plaintext)
34}