1- using System ;
2- using System . Security . Cryptography ;
3- using System . Text ;
4-
5- namespace ServiceStack . ServiceInterface . Auth
6- {
7- /// <summary>
8- /// Thank you Martijn
9- /// http://www.dijksterhuis.org/creating-salted-hash-values-in-c/
10- /// </summary>
11- public class SaltedHash
12- {
13- readonly HashAlgorithm HashProvider ;
14- readonly int SalthLength ;
15-
16- public SaltedHash ( HashAlgorithm HashAlgorithm , int theSaltLength )
17- {
18- HashProvider = HashAlgorithm ;
19- SalthLength = theSaltLength ;
20- }
21-
22- public SaltedHash ( ) : this ( new SHA256Managed ( ) , 4 ) { }
23-
24- private byte [ ] ComputeHash ( byte [ ] Data , byte [ ] Salt )
25- {
26- var DataAndSalt = new byte [ Data . Length + SalthLength ] ;
27- Array . Copy ( Data , DataAndSalt , Data . Length ) ;
28- Array . Copy ( Salt , 0 , DataAndSalt , Data . Length , SalthLength ) ;
29-
30- return HashProvider . ComputeHash ( DataAndSalt ) ;
31- }
32-
33- public void GetHashAndSalt ( byte [ ] Data , out byte [ ] Hash , out byte [ ] Salt )
34- {
35- Salt = new byte [ SalthLength ] ;
36-
37- var random = new RNGCryptoServiceProvider ( ) ;
38- random . GetNonZeroBytes ( Salt ) ;
39-
40- Hash = ComputeHash ( Data , Salt ) ;
41- }
42-
43- public void GetHashAndSaltString ( string Data , out string Hash , out string Salt )
44- {
45- byte [ ] HashOut ;
46- byte [ ] SaltOut ;
47-
48- GetHashAndSalt ( Encoding . UTF8 . GetBytes ( Data ) , out HashOut , out SaltOut ) ;
49-
50- Hash = Convert . ToBase64String ( HashOut ) ;
51- Salt = Convert . ToBase64String ( SaltOut ) ;
52- }
53-
54- public bool VerifyHash ( byte [ ] Data , byte [ ] Hash , byte [ ] Salt )
55- {
56- var NewHash = ComputeHash ( Data , Salt ) ;
57-
58- if ( NewHash . Length != Hash . Length ) return false ;
59-
60- for ( int Lp = 0 ; Lp < Hash . Length ; Lp ++ )
61- if ( ! Hash [ Lp ] . Equals ( NewHash [ Lp ] ) )
62- return false ;
63-
64- return true ;
65- }
66-
67- public bool VerifyHashString ( string Data , string Hash , string Salt )
68- {
69- byte [ ] HashToVerify = Convert . FromBase64String ( Hash ) ;
70- byte [ ] SaltToVerify = Convert . FromBase64String ( Salt ) ;
71- byte [ ] DataToVerify = Encoding . UTF8 . GetBytes ( Data ) ;
72- return VerifyHash ( DataToVerify , HashToVerify , SaltToVerify ) ;
73- }
74- }
75-
76- /*
77- /// <summary>
78- /// This little demo code shows how to encode a users password.
79- /// </summary>
80- class SaltedHashDemo
81- {
82- public static void Main(string[] args)
83- {
84- // We use the default SHA-256 & 4 byte length
85- SaltedHash demo = new SaltedHash();
86-
87- // We have a password, which will generate a Hash and Salt
88- string Password = "MyGlook234";
89- string Hash;
90- string Salt;
91-
92- demo.GetHashAndSaltString(Password, out Hash, out Salt);
93- Console.WriteLine("Password = {0} , Hash = {1} , Salt = {2}", Password, Hash, Salt);
94-
95- // Password validation
96- //
97- // We need to pass both the earlier calculated Hash and Salt (we need to store this somewhere safe between sessions)
98-
99- // First check if a wrong password passes
100- string WrongPassword = "OopsOops";
101- Console.WriteLine("Verifying {0} = {1}", WrongPassword, demo.VerifyHashString(WrongPassword, Hash, Salt));
102-
103- // Check if the correct password passes
104- Console.WriteLine("Verifying {0} = {1}", Password, demo.VerifyHashString(Password, Hash, Salt));
105- }
106- }
107- */
108-
1+ using System ;
2+ using System . Security . Cryptography ;
3+ using System . Text ;
4+
5+ namespace ServiceStack . ServiceInterface . Auth
6+ {
7+ public interface IHashProvider
8+ {
9+ void GetHashAndSalt ( byte [ ] Data , out byte [ ] Hash , out byte [ ] Salt ) ;
10+ void GetHashAndSaltString ( string Data , out string Hash , out string Salt ) ;
11+ bool VerifyHash ( byte [ ] Data , byte [ ] Hash , byte [ ] Salt ) ;
12+ bool VerifyHashString ( string Data , string Hash , string Salt ) ;
13+ }
14+
15+ /// <summary>
16+ /// Thank you Martijn
17+ /// http://www.dijksterhuis.org/creating-salted-hash-values-in-c/
18+ /// </summary>
19+ public class SaltedHash : IHashProvider
20+ {
21+ readonly HashAlgorithm HashProvider ;
22+ readonly int SalthLength ;
23+
24+ public SaltedHash ( HashAlgorithm HashAlgorithm , int theSaltLength )
25+ {
26+ HashProvider = HashAlgorithm ;
27+ SalthLength = theSaltLength ;
28+ }
29+
30+ public SaltedHash ( ) : this ( new SHA256Managed ( ) , 4 ) { }
31+
32+ private byte [ ] ComputeHash ( byte [ ] Data , byte [ ] Salt )
33+ {
34+ var DataAndSalt = new byte [ Data . Length + SalthLength ] ;
35+ Array . Copy ( Data , DataAndSalt , Data . Length ) ;
36+ Array . Copy ( Salt , 0 , DataAndSalt , Data . Length , SalthLength ) ;
37+
38+ return HashProvider . ComputeHash ( DataAndSalt ) ;
39+ }
40+
41+ public void GetHashAndSalt ( byte [ ] Data , out byte [ ] Hash , out byte [ ] Salt )
42+ {
43+ Salt = new byte [ SalthLength ] ;
44+
45+ var random = new RNGCryptoServiceProvider ( ) ;
46+ random . GetNonZeroBytes ( Salt ) ;
47+
48+ Hash = ComputeHash ( Data , Salt ) ;
49+ }
50+
51+ public void GetHashAndSaltString ( string Data , out string Hash , out string Salt )
52+ {
53+ byte [ ] HashOut ;
54+ byte [ ] SaltOut ;
55+
56+ GetHashAndSalt ( Encoding . UTF8 . GetBytes ( Data ) , out HashOut , out SaltOut ) ;
57+
58+ Hash = Convert . ToBase64String ( HashOut ) ;
59+ Salt = Convert . ToBase64String ( SaltOut ) ;
60+ }
61+
62+ public bool VerifyHash ( byte [ ] Data , byte [ ] Hash , byte [ ] Salt )
63+ {
64+ var NewHash = ComputeHash ( Data , Salt ) ;
65+
66+ if ( NewHash . Length != Hash . Length ) return false ;
67+
68+ for ( int Lp = 0 ; Lp < Hash . Length ; Lp ++ )
69+ if ( ! Hash [ Lp ] . Equals ( NewHash [ Lp ] ) )
70+ return false ;
71+
72+ return true ;
73+ }
74+
75+ public bool VerifyHashString ( string Data , string Hash , string Salt )
76+ {
77+ byte [ ] HashToVerify = Convert . FromBase64String ( Hash ) ;
78+ byte [ ] SaltToVerify = Convert . FromBase64String ( Salt ) ;
79+ byte [ ] DataToVerify = Encoding . UTF8 . GetBytes ( Data ) ;
80+ return VerifyHash ( DataToVerify , HashToVerify , SaltToVerify ) ;
81+ }
82+ }
83+
84+ /*
85+ /// <summary>
86+ /// This little demo code shows how to encode a users password.
87+ /// </summary>
88+ class SaltedHashDemo
89+ {
90+ public static void Main(string[] args)
91+ {
92+ // We use the default SHA-256 & 4 byte length
93+ SaltedHash demo = new SaltedHash();
94+
95+ // We have a password, which will generate a Hash and Salt
96+ string Password = "MyGlook234";
97+ string Hash;
98+ string Salt;
99+
100+ demo.GetHashAndSaltString(Password, out Hash, out Salt);
101+ Console.WriteLine("Password = {0} , Hash = {1} , Salt = {2}", Password, Hash, Salt);
102+
103+ // Password validation
104+ //
105+ // We need to pass both the earlier calculated Hash and Salt (we need to store this somewhere safe between sessions)
106+
107+ // First check if a wrong password passes
108+ string WrongPassword = "OopsOops";
109+ Console.WriteLine("Verifying {0} = {1}", WrongPassword, demo.VerifyHashString(WrongPassword, Hash, Salt));
110+
111+ // Check if the correct password passes
112+ Console.WriteLine("Verifying {0} = {1}", Password, demo.VerifyHashString(Password, Hash, Salt));
113+ }
114+ }
115+ */
116+
109117}
0 commit comments