1
1
use std:: fmt;
2
2
3
3
use chacha20poly1305:: {
4
- aead:: { Aead , AeadCore , KeyInit , OsRng , generic_array :: GenericArray } ,
5
- XChaCha20Poly1305 , XNonce ,
4
+ aead:: { generic_array :: typenum :: Unsigned , Aead , AeadCore , KeyInit , OsRng } ,
5
+ XChaCha20Poly1305 , XNonce
6
6
} ;
7
+ use hkdf:: Hkdf ;
8
+ use sha2:: Sha256 ;
7
9
use cookie:: Key ;
8
10
use serde:: { de, ser, Deserialize , Serialize } ;
9
11
10
12
use crate :: request:: { Outcome , Request , FromRequest } ;
11
13
12
- const NONCE_LEN : usize = 24 ; // 192-bit
13
- const KEY_LEN : usize = 32 ;
14
+ const INFO_STRING : & [ u8 ] = b"secret_key_data_encryption" ;
14
15
15
16
#[ derive( Debug ) ]
16
17
pub enum Error {
@@ -212,21 +213,18 @@ impl SecretKey {
212
213
/// assert_eq!(decrypted, plaintext);
213
214
/// ```
214
215
pub fn encrypt < T : AsRef < [ u8 ] > > ( & self , value : T ) -> Result < Vec < u8 > , Error > {
215
- // Convert the encryption key to a fixed-length array
216
- let key: [ u8 ; KEY_LEN ] = self . key
217
- . encryption ( )
218
- . try_into ( )
219
- . map_err ( |_| Error :: KeyLengthError ) ?;
220
-
221
- let cipher = XChaCha20Poly1305 :: new ( GenericArray :: from_slice ( & key) ) ;
222
216
let nonce = XChaCha20Poly1305 :: generate_nonce ( & mut OsRng ) ;
223
217
218
+ let ( mut prk, hk) = Hkdf :: < Sha256 > :: extract ( Some ( & nonce) , self . key . encryption ( ) ) ;
219
+ hk. expand ( INFO_STRING , & mut prk) . map_err ( |_| Error :: KeyLengthError ) ?;
220
+ let cipher = XChaCha20Poly1305 :: new ( & prk) ;
221
+
224
222
let ciphertext = cipher
225
223
. encrypt ( & nonce, value. as_ref ( ) )
226
224
. map_err ( |_| Error :: EncryptionError ) ?;
227
225
228
226
// Prepare a vector to hold the nonce and ciphertext
229
- let mut encrypted_data = Vec :: with_capacity ( NONCE_LEN + ciphertext. len ( ) ) ;
227
+ let mut encrypted_data = Vec :: with_capacity ( nonce . len ( ) + ciphertext. len ( ) ) ;
230
228
encrypted_data. extend_from_slice ( nonce. as_slice ( ) ) ;
231
229
encrypted_data. extend_from_slice ( & ciphertext) ;
232
230
@@ -240,21 +238,18 @@ impl SecretKey {
240
238
let encrypted = encrypted. as_ref ( ) ;
241
239
242
240
// Check if the length of decoded data is at least the length of the nonce
243
- if encrypted. len ( ) <= NONCE_LEN {
241
+ let nonce_len = <XChaCha20Poly1305 as AeadCore >:: NonceSize :: USIZE ;
242
+ if encrypted. len ( ) <= nonce_len {
244
243
return Err ( Error :: EncryptedDataLengthError ) ;
245
244
}
246
245
247
246
// Split the decoded data into nonce and ciphertext
248
- let ( nonce, ciphertext) = encrypted. split_at ( NONCE_LEN ) ;
247
+ let ( nonce, ciphertext) = encrypted. split_at ( nonce_len ) ;
249
248
let nonce = XNonce :: from_slice ( nonce) ;
250
249
251
- // Convert the encryption key to a fixed-length array
252
- let key: [ u8 ; KEY_LEN ] = self . key
253
- . encryption ( )
254
- . try_into ( )
255
- . map_err ( |_| Error :: KeyLengthError ) ?;
256
-
257
- let cipher = XChaCha20Poly1305 :: new ( GenericArray :: from_slice ( & key) ) ;
250
+ let ( mut prk, hk) = Hkdf :: < Sha256 > :: extract ( Some ( & nonce) , self . key . encryption ( ) ) ;
251
+ hk. expand ( INFO_STRING , & mut prk) . map_err ( |_| Error :: KeyLengthError ) ?;
252
+ let cipher = XChaCha20Poly1305 :: new ( & prk) ;
258
253
259
254
// Decrypt the ciphertext using the nonce
260
255
let decrypted = cipher. decrypt ( nonce, ciphertext)
0 commit comments