1- use aes_gcm:: {
2- aead:: Aead ,
3- Aes256Gcm ,
4- KeyInit ,
5- Nonce , // Or `Aes128Gcm`
6- } ;
7- use anyhow:: anyhow;
8- use base64:: { engine:: general_purpose, Engine as _} ;
91use rand:: { distributions:: Alphanumeric , Rng } ;
102use serde:: { Deserialize , Serialize } ;
11- use sqlx:: postgres:: types:: PgInterval ;
12- use time:: Duration ;
133
144/// Encrypted value that can be stored safely in
155/// any storage medium, including a database.
@@ -27,71 +17,3 @@ pub fn random_string(len: usize) -> String {
2717. map ( char:: from)
2818. collect ( )
2919}
30-
31- /// Encrypt a value using a AES-256-GCM.
32- ///
33- /// The provided key must be 256-bits, or 32 characters long.
34- pub fn encrypt ( key : & str , value : & str ) -> anyhow:: Result < String > {
35- let nonce = rand:: thread_rng ( ) . gen :: < [ u8 ; 12 ] > ( ) ;
36- let key = general_purpose:: STANDARD
37- . decode ( key)
38- . expect ( "base64 decode failed on key" ) ;
39-
40- let cipher =match Aes256Gcm :: new_from_slice ( & key) {
41- Ok ( cipher) => cipher,
42- Err ( err) =>return Err ( anyhow:: anyhow!( "key error: {:?}" , err) ) ,
43- } ;
44-
45- let nonce =Nonce :: from_slice ( & nonce) ;
46- let encrypted =match cipher. encrypt ( & nonce, value. as_bytes ( ) ) {
47- Ok ( encrypted) => encrypted,
48- Err ( err) =>return Err ( anyhow:: anyhow!( "encryption error: {:?}" , err) ) ,
49- } ;
50-
51- Ok ( serde_json:: to_string ( & EncryptedValue {
52- value : encrypted,
53- nonce : nonce. to_vec ( ) ,
54- } ) ?)
55- }
56-
57- /// Take care of unusual error casting that is required.
58- pub fn pg_duration ( dur : & Duration ) -> anyhow:: Result < PgInterval > {
59- PgInterval :: try_from ( dur. clone ( ) ) . map_err ( |err|anyhow ! ( err) )
60- }
61-
62- /// Decrypt a value using AES-256-GCM.
63- ///
64- /// The provided key must be 256-bits, or 32 characters long.
65- pub fn decrypt ( key : & str , value : & str ) -> anyhow:: Result < String > {
66- let value: EncryptedValue = serde_json:: from_str ( value) ?;
67- let key = general_purpose:: STANDARD
68- . decode ( key)
69- . expect ( "base64 decode failed on key" ) ;
70-
71- let cipher =match Aes256Gcm :: new_from_slice ( & key) {
72- Ok ( cipher) => cipher,
73- Err ( err) =>return Err ( anyhow:: anyhow!( "key error: {:?}" , err) ) ,
74- } ;
75-
76- let nonce =Nonce :: from_slice ( & value. nonce ) ;
77- let decrpyted =match cipher. decrypt ( & nonce, value. value . as_slice ( ) ) {
78- Ok ( value) => value,
79- Err ( err) =>return Err ( anyhow:: anyhow!( "decryption error: {:?}" , err) ) ,
80- } ;
81-
82- Ok ( String :: from_utf8 ( decrpyted) ?)
83- }
84-
85- #[ cfg( test) ]
86- mod test{
87- use super :: * ;
88-
89- #[ test]
90- fn test_encrypt ( ) {
91- let key ="CED3lXZ4voSifPakjydU9cUxgD5xYTrkJUpqvX1RBUA=" ;
92- let enc =encrypt ( key, "test value" ) . unwrap ( ) ;
93- let dec =decrypt ( key, & enc) . unwrap ( ) ;
94-
95- assert_eq ! ( dec. as_str( ) , "test value" ) ;
96- }
97- }