serialize_with_password/lib.rs
1//! # Serialize_with_password
2//! Small crate that adds additional layer on top of the serde crate. This crate allows to encrypt serialized data with password
3//!
4//! # Examples
5//! ## Serialization with password
6//! ```
7//! use serialize_with_password::{serialize, is_encrypted, deserialize};
8//!
9//! let example_data = b"some data";
10//! let password = b"password";
11//! let encrypted = serialize(example_data, password).unwrap();
12//!
13//! assert_ne!(example_data.to_vec(), encrypted);
14//! assert!(is_encrypted(&encrypted).expect("Correctly encrypted data always will return Ok(bool) for is_encrypted"));
15//! assert_eq!(example_data.to_vec(), deserialize(&encrypted, password).expect("Correct password"));
16//! assert!(deserialize(&encrypted, b"bacPass").is_err());
17//! ```
18//!
19//! ## Serialize without password
20//! ```
21//! use serialize_with_password::{serialize_no_pass, is_encrypted, deserialize, deserialize_no_pass};
22//!
23//! let example_data = b"some data";
24//! let encoded = serialize_no_pass(example_data);
25//!
26//! assert!(!is_encrypted(&encoded).unwrap());
27//! assert_eq!(example_data.to_vec(), deserialize_no_pass(&encoded).unwrap());
28//! assert_eq!(example_data.to_vec(), deserialize(&encoded, b"Any password").unwrap());
29//! ```
30
31extern crate chacha20poly1305;
32extern crate argon2;
33
34use chacha20poly1305::{aead::Aead, XChaCha20Poly1305, Key, KeyInit};
35pub use chacha20poly1305::Error as ChaCha20Error;
36pub use argon2::Error as Argon2Error;
37
38#[cfg(feature = "serde")]
39pub use rmp_serde::encode::Error as EncodeError;
40#[cfg(feature = "serde")]
41pub use rmp_serde::decode::Error as DecodeError;
42
43#[derive(Debug)]
44pub enum Error {
45 DataIsEncrypted,
46 DataIsEmpty,
47 Argon2Error(Argon2Error),
48 ChaCha20Error(ChaCha20Error),
49 #[cfg(feature = "serde")]
50 SerdeEncodingError(EncodeError),
51 #[cfg(feature = "serde")]
52 SerdeDecodingError(DecodeError),
53}
54
55impl std::fmt::Display for Error {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 write!(f, "{}", match self {
58 Self::DataIsEncrypted => "DataIsEncrypted".to_owned(),
59 Self::DataIsEmpty => "DataIsEmpty".to_owned(),
60 Self::Argon2Error(err) => err.to_string(),
61 Self::ChaCha20Error(err) => err.to_string(),
62 #[cfg(feature = "serde")]
63 Self::SerdeEncodingError(err) => err.to_string(),
64 #[cfg(feature = "serde")]
65 Self::SerdeDecodingError(err) => err.to_string(),
66 })
67 }
68}
69
70impl From<Argon2Error> for Error {
71 fn from(value: Argon2Error) -> Self {
72 Self::Argon2Error(value)
73 }
74}
75
76impl From<ChaCha20Error> for Error {
77 fn from(value: ChaCha20Error) -> Self {
78 Self::ChaCha20Error(value)
79 }
80}
81
82impl std::error::Error for Error { }
83
84pub type Result<T> = core::result::Result<T, Error>;
85
86const SYMMETRIC_KEY_SIZE: usize = 32;
87const SYMMETRIC_NONE_SIZE: usize = 24;
88const SALT: &'static [u8] = b"WvgoXslnFkE0qM!R#gVONUCzVk2BeT!lSQ3$qnMLJ6q5dTbB3RrXRERlV2qAc%XMrN#A5f3P3W&!HUvznbqIFTnS3OdyYu3&lzEvLjItAamR8JN8wjR%Y0MPpzfE3ha7";
89
90#[inline]
91fn compute_key_and_nonce(password: &[u8]) -> core::result::Result<(Key, [u8; SYMMETRIC_NONE_SIZE]), Argon2Error> {
92 let mut dig = vec![0; SYMMETRIC_KEY_SIZE + SYMMETRIC_NONE_SIZE];
93 let mut key = [0; SYMMETRIC_KEY_SIZE];
94 let mut iv = [0; SYMMETRIC_NONE_SIZE];
95 argon2::Argon2::default().hash_password_into(password, SALT, &mut dig)?;
96 dig.iter().take(SYMMETRIC_KEY_SIZE).enumerate().for_each(|(i, v)| key[i] = *v);
97 dig.into_iter().skip(SYMMETRIC_KEY_SIZE).enumerate().for_each(|(i, v)| iv[i] = v);
98 Ok((Key::from(key), iv))
99}
100
101/// Encrypt data using password
102///
103/// # Example
104/// ```
105/// use serialize_with_password::{serialize, is_encrypted, deserialize, deserialize_no_pass};
106///
107/// let example_data = b"some data";
108/// let password = b"password";
109/// let encrypted = serialize(example_data, password).unwrap();
110///
111/// assert!(is_encrypted(&encrypted).expect("Data is encrypted correctly"));
112/// assert_ne!(example_data.to_vec(), encrypted);
113/// assert_eq!(example_data.to_vec(), deserialize(&encrypted, password).expect("Correct password"));
114/// assert!(deserialize(&encrypted, b"bacPass").is_err());
115/// assert!(deserialize_no_pass(&encrypted).is_err());
116/// ```
117#[inline]
118pub fn serialize(data: &[u8], password: &[u8]) -> Result<Vec<u8>> {
119 let (key, nonce) = compute_key_and_nonce(password)?;
120 let mut ans = vec![1];
121 ans.append(&mut XChaCha20Poly1305::new(&key).encrypt(&nonce.into(), data)?);
122 Ok(ans)
123}
124
125/// Serialize data without password
126///
127/// # Example
128/// ```
129/// use serialize_with_password::{serialize_no_pass, is_encrypted, deserialize, deserialize_no_pass};
130///
131/// let example_data = b"some data";
132/// let encoded = serialize_no_pass(example_data);
133///
134/// assert!(!is_encrypted(&encoded).expect("Data is encrypted correctly"));
135/// assert_eq!(example_data.to_vec(), deserialize_no_pass(&encoded).expect("Correctly serialized data will always return Ok(_)"));
136/// assert_eq!(example_data.to_vec(), deserialize(&encoded, b"any string of bytes").expect("Data serialized without password can be deserialized with any password"));
137/// ```
138#[inline]
139pub fn serialize_no_pass(data: &[u8]) -> Vec<u8> {
140 let mut ans = vec![0];
141 ans.extend(data.into_iter());
142 ans
143}
144
145
146/// Decrypt data with given password
147///
148/// # Error
149/// - if `data` slice is empty (Error::DataIsEmpty)
150/// - if `argon2` hasgin function return Error (Error::Argon2Error(Argon2Error))
151/// - if `password` is incorrect (Error::ChaCha20Error(ChaCha20Error))
152///
153/// # Example
154/// ```
155/// use serialize_with_password::{serialize, serialize_no_pass, is_encrypted, deserialize};
156///
157/// let example_data = b"some data";
158/// let encoded = serialize_no_pass(example_data);
159/// let password = b"password";
160/// let encrypted = serialize(example_data, password).unwrap();
161///
162/// assert!(!is_encrypted(&encoded).expect("Data is encrypted correctly"));
163/// assert!(is_encrypted(&encrypted).expect("Data is encrypted correctly"));
164/// assert_eq!(example_data.to_vec(), deserialize(&encoded, b"any string of bytes").expect("Data serialized without password can be deserialized with any password"));
165/// assert_eq!(example_data.to_vec(), deserialize(&encrypted, password).expect("Correct password"));
166/// assert!(deserialize(&encrypted, b"Wrong password").is_err());
167/// ```
168#[inline]
169pub fn deserialize(data: &[u8], password: &[u8]) -> Result<Vec<u8>> {
170 if data.is_empty() {
171 return Err(Error::DataIsEmpty);
172 }
173 if data[0] == 0 {
174 return Ok(data[1..].to_vec());
175 }
176 let (key, nonce) = compute_key_and_nonce(password)?;
177 Ok(XChaCha20Poly1305::new(&key).decrypt(&nonce.into(), &data[1..])?)
178}
179
180/// Deserialize data
181///
182/// # Error
183/// - if `data` slice is empty (Error::DataIsEmpty)
184/// - if `data` is encrypted (Error::DataIsEncrypted)
185///
186/// # Example
187/// ```
188/// use serialize_with_password::{serialize, is_encrypted, serialize_no_pass, deserialize_no_pass};
189///
190/// let example_data = b"some data";
191/// let encoded = serialize_no_pass(example_data);
192/// let password = b"password";
193/// let encrypted = serialize(example_data, password).unwrap();
194///
195/// assert!(!is_encrypted(&encoded).expect("Data is encrypted correctly"));
196/// assert!(is_encrypted(&encrypted).expect("Data is encrypted correctly"));
197/// assert_eq!(example_data.to_vec(), deserialize_no_pass(&encoded).expect("Data is serialized correctly"));
198/// assert!(deserialize_no_pass(&encrypted).is_err());
199/// assert!(deserialize_no_pass(&encrypted).is_err());
200/// ```
201#[inline]
202pub fn deserialize_no_pass(data: &[u8]) -> Result<Vec<u8>> {
203 if !is_encrypted(data)? {
204 return Ok(data[1..].to_vec());
205 }
206 Err(Error::DataIsEncrypted)
207}
208
209/// Returns whether data is encrypted
210/// For random non empty data returns random bool value
211///
212/// # Error
213/// Only if data is empty (Error::DataIsEmpty)
214///
215/// # Example
216/// ```
217/// use serialize_with_password::{serialize, serialize_no_pass, is_encrypted, deserialize_no_pass};
218///
219/// let example_data = b"some data";
220/// let encoded = serialize_no_pass(example_data);
221/// let password = b"password";
222/// let encrypted = serialize(example_data, password).unwrap();
223///
224/// assert!(!is_encrypted(&encoded).expect("Data is encoded correctly"));
225/// assert!(is_encrypted(&encrypted).expect("Data is encrypted correctly"));
226/// assert!(is_encrypted(&Vec::new()).is_err());
227/// ```
228#[inline]
229pub fn is_encrypted(data: &[u8]) -> Result<bool> {
230 if data.is_empty() {
231 return Err(Error::DataIsEmpty);
232 }
233 Ok(data[0] == 1)
234}
235
236#[cfg(feature = "serde")]
237mod serde_feature {
238 //! bbbb# Examples
239 //!
240 //! ## Serialize serde with password
241 //!
242 //! ```
243 //! use serde::{Serialize, Deserialize};
244 //! use serialize_with_password::{serialize_serde, is_encrypted, deserialize_serde};
245 //!
246 //! #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
247 //! struct ExampleStruct {
248 //! data: i32,
249 //! more_data: Vec<u8>,
250 //! }
251 //!
252 //! let example_data = ExampleStruct{ data: 16, more_data: vec![5,2,41,2] };
253 //! let password = b"password";
254 //! let encrypted = serialize_serde(&example_data, password).unwrap();
255 //! assert!(is_encrypted(&encrypted).unwrap());
256 //! assert_eq!(example_data, deserialize_serde(&encrypted, password).unwrap());
257 //! assert!(deserialize_serde::<ExampleStruct>(&encrypted, b"bacPass").is_err());
258 //! ```
259 //!
260 //! ## Serialize serde without password
261 //!
262 //! ```
263 //! use serde::{Serialize, Deserialize};
264 //! use serialize_with_password::{serialize_serde_no_pass, is_encrypted, deserialize_serde, deserialize_serde_no_pass};
265 //!
266 //! #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
267 //! struct ExampleStruct {
268 //! data: i32,
269 //! more_data: Vec<u8>,
270 //! }
271 //!
272 //! let example_data = ExampleStruct{ data: 16, more_data: vec![5,2,41,2] };
273 //! let encoded = serialize_serde_no_pass(&example_data).unwrap();
274 //! assert!(!is_encrypted(&encoded).unwrap());
275 //! assert_eq!(example_data, deserialize_serde_no_pass(&encoded).unwrap());
276 //! assert_eq!(example_data, deserialize_serde(&encoded, b"asdhas").unwrap());
277 //! ```
278
279 extern crate serde;
280 extern crate rmp_serde;
281
282 pub use serde::{Serialize, Deserialize};
283 use super::*;
284
285 impl From<EncodeError> for Error {
286 fn from(value: EncodeError) -> Self {
287 Self::SerdeEncodingError(value)
288 }
289 }
290
291 impl From<DecodeError> for Error {
292 fn from(value: DecodeError) -> Self {
293 Self::SerdeDecodingError(value)
294 }
295 }
296
297 /// Serialize data with serde then encrypt it
298 ///
299 /// # Example
300 /// ```
301 /// use serde::{Serialize, Deserialize};
302 /// use serialize_with_password::{serialize_serde, is_encrypted, deserialize_serde, deserialize_serde_no_pass};
303 ///
304 /// #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
305 /// struct ExampleStruct {
306 /// data: i32,
307 /// more_data: Vec<u8>,
308 /// }
309 ///
310 /// let example_data = ExampleStruct{ data: 16, more_data: vec![5,2,41,2] };
311 /// let password = b"password";
312 /// let encrypted = serialize_serde(&example_data, password).unwrap();
313 ///
314 /// assert!(is_encrypted(&encrypted).expect("Data is encrypted correctly"));
315 /// assert_eq!(example_data, deserialize_serde(&encrypted, password).unwrap());
316 /// assert!(deserialize_serde::<ExampleStruct>(&encrypted, b"badPass").is_err());
317 /// assert!(deserialize_serde_no_pass::<ExampleStruct>(&encrypted).is_err());
318 /// ```
319 #[inline]
320 pub fn serialize_serde<T: Serialize>(data: &T, password: &[u8]) -> Result<Vec<u8>> {
321 Ok(serialize(&rmp_serde::to_vec(data)?, password)?)
322 }
323
324 /// Serialize data with serde
325 ///
326 /// # Example
327 /// ```
328 /// use serde::{Serialize, Deserialize};
329 /// use serialize_with_password::{serialize_serde_no_pass, is_encrypted, deserialize_serde, deserialize_serde_no_pass};
330 ///
331 /// #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
332 /// struct ExampleStruct {
333 /// data: i32,
334 /// more_data: Vec<u8>,
335 /// }
336 ///
337 /// let example_data = ExampleStruct{ data: 16, more_data: vec![5,2,41,2] };
338 /// let encoded = serialize_serde_no_pass(&example_data).unwrap();
339 ///
340 /// assert!(!is_encrypted(&encoded).expect("Data is encrypted correctly"));
341 /// assert_eq!(example_data, deserialize_serde_no_pass(&encoded).unwrap());
342 /// assert_eq!(example_data, deserialize_serde(&encoded, b"Any password").unwrap());
343 /// ```
344 #[inline]
345 pub fn serialize_serde_no_pass<T: Serialize>(data: &T) -> Result<Vec<u8>> {
346 Ok(serialize_no_pass(&rmp_serde::to_vec(data)?))
347 }
348
349 /// Decrypt data and deserialize it with serde
350 ///
351 /// # Example
352 /// ```
353 /// use serde::{Serialize, Deserialize};
354 /// use serialize_with_password::{serialize_serde, serialize_serde_no_pass, is_encrypted, deserialize_serde};
355 ///
356 /// #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
357 /// struct ExampleStruct {
358 /// data: i32,
359 /// more_data: Vec<u8>,
360 /// }
361 ///
362 /// let example_data = ExampleStruct{ data: 16, more_data: vec![5,2,41,2] };
363 /// let encoded = serialize_serde_no_pass(&example_data).unwrap();
364 /// let password = b"password";
365 /// let encrypted = serialize_serde(&example_data, password).unwrap();
366 ///
367 /// assert!(!is_encrypted(&encoded).expect("Data is encoded correctly"));
368 /// assert!(is_encrypted(&encrypted).expect("Data is encrypted correctly"));
369 /// assert_eq!(example_data, deserialize_serde(&encoded, b"Any password").unwrap());
370 /// assert_eq!(example_data, deserialize_serde(&encrypted, password).unwrap());
371 /// assert!(deserialize_serde::<ExampleStruct>(&encrypted, b"badPass").is_err());
372 /// ```
373 #[inline]
374 pub fn deserialize_serde<T: for<'a> Deserialize<'a>>(data: &[u8], password: &[u8]) -> Result<T> {
375 Ok(rmp_serde::from_slice(&deserialize(data, password)?)?)
376 }
377
378 /// Deserialize data with serde
379 ///
380 /// # Example
381 /// ```
382 /// use serde::{Serialize, Deserialize};
383 /// use serialize_with_password::{serialize_serde, serialize_serde_no_pass, is_encrypted, deserialize_serde_no_pass};
384 ///
385 /// #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
386 /// struct ExampleStruct {
387 /// data: i32,
388 /// more_data: Vec<u8>,
389 /// }
390 ///
391 /// let example_data = ExampleStruct{ data: 16, more_data: vec![5,2,41,2] };
392 /// let encoded = serialize_serde_no_pass(&example_data).unwrap();
393 /// let password = b"password";
394 /// let encrypted = serialize_serde(&example_data, password).unwrap();
395 ///
396 /// assert!(!is_encrypted(&encoded).expect("Data is encoded correctly"));
397 /// assert!(is_encrypted(&encrypted).expect("Data is encrypted correctly"));
398 /// assert_eq!(example_data, deserialize_serde_no_pass(&encoded).unwrap());
399 /// assert!(deserialize_serde_no_pass::<ExampleStruct>(&encrypted).is_err());
400 /// ```
401 #[inline]
402 pub fn deserialize_serde_no_pass<T: for<'a> Deserialize<'a>>(data: &[u8]) -> Result<T> {
403 Ok(rmp_serde::from_slice(&deserialize_no_pass(data)?)?)
404 }
405}
406
407#[cfg(feature = "serde")]
408pub use serde_feature::*;