1- using System . IO ;
2- using System . Linq ;
1+ using System ;
32using System . Security . Cryptography ;
43
54namespace NETworkManager . Utilities
65{
76 public static class CryptoHelper
87 {
8+ private static readonly int blockSize = 128 ;
99 /// <summary>
1010 ///
1111 /// </summary>
1212 /// <param name="decryptedBytes"></param>
1313 /// <param name="password"></param>
1414 /// <param name="keySize"></param>
15- /// <param name="blockSize"></param>
1615 /// <param name="iterations"></param>
1716 /// <returns></returns>
18- public static byte [ ] Encrypt ( byte [ ] decryptedBytes , string password , int keySize , int blockSize , int iterations )
17+ public static byte [ ] Encrypt ( byte [ ] decryptedBytes , string password , int keySize , int iterations )
1918 {
20- var salt = RandomNumberGenerator . GetBytes ( keySize / 8 ) ; // Generate salt based
21- var iv = RandomNumberGenerator . GetBytes ( blockSize / 8 ) ; // Generate iv, has to be the same as the block size
19+ ReadOnlySpan < byte > salt = RandomNumberGenerator . GetBytes ( keySize / 8 ) ; // Generate salt based
20+ ReadOnlySpan < byte > iv = RandomNumberGenerator . GetBytes ( blockSize / 8 ) ; // Generate iv, has to be the same as the block size
2221
23- using var rfc2898DeriveBytes = new Rfc2898DeriveBytes ( password , salt , iterations ) ;
24-
25- var key = rfc2898DeriveBytes . GetBytes ( keySize / 8 ) ;
22+ byte [ ] key = Rfc2898DeriveBytes . Pbkdf2 ( password , salt , iterations , HashAlgorithmName . SHA512 , keySize / 8 ) ;
2623
2724 using Aes aes = Aes . Create ( ) ;
25+ aes . Key = key ;
2826
29- aes . KeySize = keySize ;
30- aes . BlockSize = blockSize ;
31- aes . Mode = CipherMode . CBC ;
32- aes . Padding = PaddingMode . PKCS7 ;
27+ int encryptedSize = aes . GetCiphertextLengthCbc ( decryptedBytes . Length ) ;
3328
34- using var encryptor = aes . CreateEncryptor ( key , iv ) ;
35- using var memoryStream = new MemoryStream ( ) ;
36- using var cryptoStream = new CryptoStream ( memoryStream , encryptor , CryptoStreamMode . Write ) ;
29+ byte [ ] cipher = new byte [ salt . Length + iv . Length + encryptedSize ] ;
3730
38- cryptoStream . Write ( decryptedBytes , 0 , decryptedBytes . Length ) ;
39- cryptoStream . FlushFinalBlock ( ) ;
31+ Span < byte > cipherSpan = cipher ;
4032
41- var cipher = salt ;
42- cipher = cipher . Concat ( iv ) . ToArray ( ) ;
43- cipher = cipher . Concat ( memoryStream . ToArray ( ) ) . ToArray ( ) ;
33+ salt . CopyTo ( cipherSpan ) ;
34+ iv . CopyTo ( cipherSpan [ salt . Length ..] ) ;
4435
45- memoryStream . Close ( ) ;
46- cryptoStream . Close ( ) ;
36+ int encrypted = aes . EncryptCbc ( decryptedBytes , iv , cipherSpan [ ( salt . Length + iv . Length ) ..] ) ;
4737
4838 return cipher ;
4939 }
@@ -54,50 +44,20 @@ public static byte[] Encrypt(byte[] decryptedBytes, string password, int keySize
5444 /// <param name="encryptedBytesWithSaltAndIV"></param>
5545 /// <param name="password"></param>
5646 /// <param name="keySize"></param>
57- /// <param name="blockSize"></param>
5847 /// <param name="iterations"></param>
5948 /// <returns></returns>
60- public static byte [ ] Decrypt ( byte [ ] encryptedBytesWithSaltAndIV , string password , int keySize , int blockSize , int iterations )
49+ public static byte [ ] Decrypt ( byte [ ] encryptedBytesWithSaltAndIV , string password , int keySize , int iterations )
6150 {
62- var salt = encryptedBytesWithSaltAndIV . Take ( keySize / 8 ) . ToArray ( ) ; // Take salt bytes
63- var iv = encryptedBytesWithSaltAndIV . Skip ( keySize / 8 ) . Take ( blockSize / 8 ) . ToArray ( ) ; // Skip salt bytes, take iv bytes
64- var cipher = encryptedBytesWithSaltAndIV . Skip ( ( keySize / 8 ) + ( blockSize / 8 ) ) . Take ( encryptedBytesWithSaltAndIV . Length - ( ( keySize / 8 ) + ( blockSize / 8 ) ) ) . ToArray ( ) ; // Skip salt and iv bytes, take cipher bytes
65-
66- using var rfc2898DeriveBytes = new Rfc2898DeriveBytes ( password , salt , iterations ) ;
51+ ReadOnlySpan < byte > salt = encryptedBytesWithSaltAndIV . AsSpan ( 0 , keySize / 8 ) ; // Take salt bytes
52+ ReadOnlySpan < byte > iv = encryptedBytesWithSaltAndIV . AsSpan ( keySize / 8 , blockSize / 8 ) ; // Skip salt bytes, take iv bytes
53+ ReadOnlySpan < byte > cipher = encryptedBytesWithSaltAndIV . AsSpan ( ( keySize / 8 ) + ( blockSize / 8 ) ) ;
6754
68- var key = rfc2898DeriveBytes . GetBytes ( keySize / 8 ) ;
55+ byte [ ] key = Rfc2898DeriveBytes . Pbkdf2 ( password , salt , iterations , HashAlgorithmName . SHA512 , keySize / 8 ) ;
6956
7057 using Aes aes = Aes . Create ( ) ;
58+ aes . Key = key ;
7159
72- aes . KeySize = keySize ;
73- aes . BlockSize = blockSize ;
74- aes . Mode = CipherMode . CBC ;
75- aes . Padding = PaddingMode . PKCS7 ;
76-
77- using var decryptor = aes . CreateDecryptor ( key , iv ) ;
78- using var memoryStream = new MemoryStream ( cipher ) ;
79- using var cryptoStream = new CryptoStream ( memoryStream , decryptor , CryptoStreamMode . Read ) ;
80-
81- var text = new byte [ cipher . Length ] ;
82-
83- //cryptoStream.Read(text, 0, text.Length);
84- // Fix for issue: https://github.com/dotnet/runtime/issues/61535
85-
86- int readBytes = 0 ;
87- while ( readBytes < text . Length )
88- {
89- int n = cryptoStream . Read ( text , readBytes , text . Length - readBytes ) ;
90-
91- if ( n == 0 )
92- break ;
93-
94- readBytes += n ;
95- }
96-
97- memoryStream . Close ( ) ;
98- cryptoStream . Close ( ) ;
99-
100- return text ;
60+ return aes . DecryptCbc ( cipher , iv ) ;
10161 }
10262 }
10363}
0 commit comments