@@ -23,19 +23,26 @@ impl fmt::Display for CoreError {
23
23
24
24
impl error:: Error for CoreError { }
25
25
26
- pub fn encrypt_string ( plaintext : & mut String , password : & str ) -> String {
26
+ fn argon_derive_key ( key : & mut [ u8 ; 32 ] , password_bytes : & [ u8 ] , salt : & pwhash:: argon2id13:: Salt ) -> Result < Key , String > {
27
+ let result = pwhash:: argon2id13:: derive_key ( key, password_bytes, salt,
28
+ pwhash:: argon2id13:: OPSLIMIT_INTERACTIVE ,
29
+ pwhash:: argon2id13:: MEMLIMIT_INTERACTIVE ) ;
30
+ match result{
31
+ Ok ( & [ u8] ) => Ok ( Key ( * key) ) ,
32
+ Ok ( & [ ] ) => Ok ( Key ( * key) ) ,
33
+ Ok ( & [ _, _, ..] ) =>Ok ( Key ( * key) ) ,
34
+ Err ( ( ) ) => Err ( String :: from ( "Failed to derive encryption key" ) )
35
+ }
36
+ }
37
+
38
+ pub fn encrypt_string ( plaintext : String , password : & str ) -> String {
27
39
let mut encrypted = String :: new ( ) ;
28
40
encrypted. push_str ( & base64:: encode ( SIGNATURE ) ) ;
29
41
encrypted. push ( '|' ) ;
30
- let salt = pwhash:: gen_salt ( ) ;
42
+ let salt = pwhash:: argon2id13 :: gen_salt ( ) ;
31
43
encrypted. push_str ( & base64:: encode ( salt. 0 ) ) ;
32
44
encrypted. push ( '|' ) ;
33
- let mut key = [ 0u8 ; KEYBYTES ] ;
34
- pwhash:: derive_key ( & mut key, password. as_bytes ( ) , & salt,
35
- pwhash:: OPSLIMIT_INTERACTIVE ,
36
- pwhash:: MEMLIMIT_INTERACTIVE ) . unwrap ( ) ;
37
- let key = Key ( key) ;
38
-
45
+ let key = argon_derive_key ( & mut [ 0u8 ; KEYBYTES ] , password. as_bytes ( ) , & salt) . unwrap ( ) ;
39
46
let ( mut enc_stream, header) = Stream :: init_push ( & key) . unwrap ( ) ;
40
47
41
48
encrypted. push_str ( & base64:: encode ( header. 0 ) ) ;
@@ -47,19 +54,19 @@ pub fn encrypt_string(plaintext: &mut String,password: &str) -> String {
47
54
encrypted
48
55
}
49
56
50
- pub fn decrypt_string ( encrypted_text : & mut str , password : & str ) -> Result < String , String > {
57
+ pub fn decrypt_string ( encrypted_text : & str , password : & str ) -> Result < String , String > {
51
58
let split = encrypted_text. split ( '|' ) ;
52
59
let vec: Vec < & str > = split. collect ( ) ;
53
60
let byte_salt = base64:: decode ( vec[ 1 ] ) . unwrap ( ) ;
54
- let salt = pwhash:: Salt ( byte_vec_to_byte_array ( byte_salt) ) ;
61
+ let salt = pwhash:: argon2id13 :: Salt ( byte_vec_to_byte_array ( byte_salt) ) ;
55
62
let byte_header = base64:: decode ( vec[ 2 ] ) . unwrap ( ) ;
56
63
let header = Header ( header_vec_to_header_array ( byte_header) ) ;
57
64
let cipher = base64:: decode ( vec[ 3 ] ) . unwrap ( ) ;
58
65
59
66
let mut key = [ 0u8 ; KEYBYTES ] ;
60
- pwhash:: derive_key ( & mut key, password. as_bytes ( ) , & salt,
61
- pwhash:: OPSLIMIT_INTERACTIVE ,
62
- pwhash:: MEMLIMIT_INTERACTIVE )
67
+ pwhash:: argon2id13 :: derive_key ( & mut key, password. as_bytes ( ) , & salt,
68
+ pwhash:: argon2id13 :: OPSLIMIT_INTERACTIVE ,
69
+ pwhash:: argon2id13 :: MEMLIMIT_INTERACTIVE )
63
70
. map_err ( |_| CoreError :: new ( "Deriving key failed" ) ) . unwrap ( ) ;
64
71
let key = Key ( key) ;
65
72
@@ -74,9 +81,9 @@ pub fn decrypt_string(encrypted_text: &mut str,password: &str) -> Result<String,
74
81
Ok ( String :: from_utf8 ( decrypted) . unwrap ( ) )
75
82
}
76
83
77
- fn byte_vec_to_byte_array ( byte_vec : Vec < u8 > ) -> [ u8 ; 32 ] {
84
+ fn byte_vec_to_byte_array ( byte_vec : Vec < u8 > ) -> [ u8 ; 16 ] {
78
85
byte_vec. try_into ( )
79
- . unwrap_or_else ( |v : Vec < u8 > | panic ! ( "Expected a Vec of length {} but it was {}" , 32 , v. len( ) ) )
86
+ . unwrap_or_else ( |v : Vec < u8 > | panic ! ( "Expected a Vec of length {} but it was {}" , 16 , v. len( ) ) )
80
87
}
81
88
82
89
fn header_vec_to_header_array ( byte_vec : Vec < u8 > ) -> [ u8 ; 24 ] {
@@ -93,4 +100,20 @@ pub fn prompt_for_passwords(message: &str) -> String{
93
100
}
94
101
}
95
102
password
103
+ }
104
+
105
+
106
+ #[ cfg( test) ]
107
+ mod tests {
108
+ use super :: { encrypt_string, decrypt_string} ;
109
+ #[ test]
110
+ fn test_encryption ( ) {
111
+ assert_eq ! (
112
+ String :: from( "Secret data@#[]ò" ) ,
113
+ decrypt_string(
114
+ & mut encrypt_string( String :: from( "Secret data@#[]ò" ) , "pa$$w0rd" ) ,
115
+ "pa$$w0rd"
116
+ ) . unwrap( )
117
+ ) ;
118
+ }
96
119
}
0 commit comments