Modify fields encryption, can selectively encrypt and fields that are not decrypted stay as they are

This commit is contained in:
Sosthene 2024-10-07 11:15:22 +02:00 committed by Nicolas Cantu
parent 8e42596184
commit c3c6549339

View File

@ -92,6 +92,7 @@ pub trait Pcd<'a>: Serialize + Deserialize<'a> {
fn encrypt_fields( fn encrypt_fields(
&self, &self,
fields_to_encrypt: &[String],
fields2keys: &mut Map<String, Value>, fields2keys: &mut Map<String, Value>,
fields2cipher: &mut Map<String, Value>, fields2cipher: &mut Map<String, Value>,
) -> Result<()> { ) -> Result<()> {
@ -102,28 +103,32 @@ pub trait Pcd<'a>: Serialize + Deserialize<'a> {
let mut rng = thread_rng(); let mut rng = thread_rng();
for (field, value) in as_map { for (field, value) in as_map {
let aes_key = Aes256Gcm::generate_key(&mut rng); if fields_to_encrypt.contains(field) {
let nonce = Aes256Gcm::generate_nonce(&mut rng); let aes_key = Aes256Gcm::generate_key(&mut rng);
fields2keys.insert( let nonce = Aes256Gcm::generate_nonce(&mut rng);
field.to_owned(), fields2keys.insert(
Value::String(aes_key.to_lower_hex_string()), field.to_owned(),
); Value::String(aes_key.to_lower_hex_string()),
);
let encrypt_eng = Aes256Gcm::new(&aes_key); let encrypt_eng = Aes256Gcm::new(&aes_key);
let value_string = value.to_string(); let value_string = value.to_string();
let payload = Payload { let payload = Payload {
msg: value_string.as_bytes(), msg: value_string.as_bytes(),
aad: AAD, aad: AAD,
}; };
let cipher = encrypt_eng let cipher = encrypt_eng
.encrypt(&nonce, payload) .encrypt(&nonce, payload)
.map_err(|e| Error::msg(format!("Encryption failed for field {}: {}", field, e)))?; .map_err(|e| Error::msg(format!("Encryption failed for field {}: {}", field, e)))?;
let mut res = Vec::with_capacity(nonce.len() + cipher.len()); let mut res = Vec::with_capacity(nonce.len() + cipher.len());
res.extend_from_slice(&nonce); res.extend_from_slice(&nonce);
res.extend_from_slice(&cipher); res.extend_from_slice(&cipher);
fields2cipher.insert(field.to_owned(), Value::String(res.to_lower_hex_string())); fields2cipher.insert(field.to_owned(), Value::String(res.to_lower_hex_string()));
} else {
fields2cipher.insert(field.to_owned(), value.clone());
}
} }
Ok(()) Ok(())
@ -169,7 +174,8 @@ pub trait Pcd<'a>: Serialize + Deserialize<'a> {
fields2plain.insert(field.to_owned(), Value::String(decrypted_value)); fields2plain.insert(field.to_owned(), Value::String(decrypted_value));
} else { } else {
fields2plain.insert(field.to_owned(), Value::Null); // We keep the original value, that allows us to have fields that are always left unencrypted
fields2plain.insert(field.to_owned(), encrypted_value.clone());
} }
} }