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 _} ;
9
1
use rand:: { distributions:: Alphanumeric , Rng } ;
10
2
use serde:: { Deserialize , Serialize } ;
11
- use sqlx:: postgres:: types:: PgInterval ;
12
- use time:: Duration ;
13
3
14
4
/// Encrypted value that can be stored safely in
15
5
/// any storage medium, including a database.
@@ -27,71 +17,3 @@ pub fn random_string(len: usize) -> String {
27
17
. map ( char:: from)
28
18
. collect ( )
29
19
}
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
- }
0 commit comments