@@ -52,6 +52,7 @@ public partial class CredentialDialog : Component
5252 {
5353 private string _confirmTarget ;
5454 private NetworkCredential _credentials = new NetworkCredential ( ) ;
55+ private byte [ ] _additionalEntropy ;
5556 private bool _isSaveChecked ;
5657 private string _target ;
5758
@@ -163,6 +164,27 @@ private set
163164 }
164165 }
165166
167+ /// <summary>
168+ /// Gets or sets the optional entropy to increase the complexity of the password encryption.
169+ /// This property is only used if the user chose to save the credentials.
170+ /// </summary>
171+ /// <value>
172+ /// A byte array with values of your choosing.
173+ /// The default value is <see langword="null" /> for no added complexity.
174+ /// </value>
175+ [ Browsable ( false ) ]
176+ public byte [ ] AdditionalEntropy
177+ {
178+ get
179+ {
180+ return _additionalEntropy ;
181+ }
182+ set
183+ {
184+ _additionalEntropy = value ;
185+ }
186+ }
187+
166188 /// <summary>
167189 /// Gets the user-specified user name and password in a <see cref="NetworkCredential"/> object.
168190 /// </summary>
@@ -551,7 +573,7 @@ public void ConfirmCredentials(bool confirm)
551573 }
552574 }
553575
554- StoreCredential ( Target , Credentials ) ;
576+ StoreCredential ( Target , Credentials , AdditionalEntropy ) ;
555577 }
556578 }
557579
@@ -560,6 +582,7 @@ public void ConfirmCredentials(bool confirm)
560582 /// </summary>
561583 /// <param name="target">The target name for the credentials.</param>
562584 /// <param name="credential">The credentials to store.</param>
585+ /// <param name="additionalEntropy">Additional entropy for encrypting the password.</param>
563586 /// <exception cref="ArgumentNullException">
564587 /// <para>
565588 /// <paramref name="target"/> is <see langword="null" />.
@@ -585,7 +608,7 @@ public void ConfirmCredentials(bool confirm)
585608 /// form "Company_ApplicationName_www.example.com".
586609 /// </para>
587610 /// </remarks>
588- public static void StoreCredential ( string target , NetworkCredential credential )
611+ public static void StoreCredential ( string target , NetworkCredential credential , byte [ ] additionalEntropy = null )
589612 {
590613 if ( target == null )
591614 throw new ArgumentNullException ( "target" ) ;
@@ -598,7 +621,7 @@ public static void StoreCredential(string target, NetworkCredential credential)
598621 c . UserName = credential . UserName ;
599622 c . TargetName = target ;
600623 c . Persist = NativeMethods . CredPersist . Enterprise ;
601- byte [ ] encryptedPassword = EncryptPassword ( credential . Password ) ;
624+ byte [ ] encryptedPassword = EncryptPassword ( credential . Password , additionalEntropy ) ;
602625 c . CredentialBlob = System . Runtime . InteropServices . Marshal . AllocHGlobal ( encryptedPassword . Length ) ;
603626 try
604627 {
@@ -618,6 +641,7 @@ public static void StoreCredential(string target, NetworkCredential credential)
618641 /// Retrieves credentials for the specified target from the operating system's credential store for the current user.
619642 /// </summary>
620643 /// <param name="target">The target name for the credentials.</param>
644+ /// <param name="additionalEntropy">The same entropy value that was used when storing the credentials.</param>
621645 /// <returns>The credentials if they were found; otherwise, <see langword="null" />.</returns>
622646 /// <remarks>
623647 /// <para>
@@ -632,7 +656,7 @@ public static void StoreCredential(string target, NetworkCredential credential)
632656 /// <exception cref="ArgumentNullException"><paramref name="target"/> is <see langword="null" />.</exception>
633657 /// <exception cref="ArgumentException"><paramref name="target"/> is an empty string ("").</exception>
634658 /// <exception cref="CredentialException">An error occurred retrieving the credentials.</exception>
635- public static NetworkCredential RetrieveCredential ( string target )
659+ public static NetworkCredential RetrieveCredential ( string target , byte [ ] additionalEntropy = null )
636660 {
637661 if ( target == null )
638662 throw new ArgumentNullException ( "target" ) ;
@@ -653,7 +677,7 @@ public static NetworkCredential RetrieveCredential(string target)
653677 NativeMethods . CREDENTIAL c = ( NativeMethods . CREDENTIAL ) System . Runtime . InteropServices . Marshal . PtrToStructure ( credential , typeof ( NativeMethods . CREDENTIAL ) ) ;
654678 byte [ ] encryptedPassword = new byte [ c . CredentialBlobSize ] ;
655679 System . Runtime . InteropServices . Marshal . Copy ( c . CredentialBlob , encryptedPassword , 0 , encryptedPassword . Length ) ;
656- cred = new NetworkCredential ( c . UserName , DecryptPassword ( encryptedPassword ) ) ;
680+ cred = new NetworkCredential ( c . UserName , DecryptPassword ( encryptedPassword , additionalEntropy ) ) ;
657681 }
658682 finally
659683 {
@@ -896,7 +920,7 @@ private NativeMethods.CREDUI_INFO CreateCredUIInfo(IntPtr owner, bool downlevelT
896920
897921 private bool RetrieveCredentials ( )
898922 {
899- NetworkCredential credential = RetrieveCredential ( Target ) ;
923+ NetworkCredential credential = RetrieveCredential ( Target , AdditionalEntropy ) ;
900924 if ( credential != null )
901925 {
902926 UserName = credential . UserName ;
@@ -906,17 +930,17 @@ private bool RetrieveCredentials()
906930 return false ;
907931 }
908932
909- private static byte [ ] EncryptPassword ( string password )
933+ private static byte [ ] EncryptPassword ( string password , byte [ ] additionalEntropy )
910934 {
911- byte [ ] protectedData = System . Security . Cryptography . ProtectedData . Protect ( System . Text . Encoding . UTF8 . GetBytes ( password ) , null , System . Security . Cryptography . DataProtectionScope . CurrentUser ) ;
935+ byte [ ] protectedData = System . Security . Cryptography . ProtectedData . Protect ( System . Text . Encoding . UTF8 . GetBytes ( password ) , additionalEntropy , System . Security . Cryptography . DataProtectionScope . CurrentUser ) ;
912936 return protectedData ;
913937 }
914938
915- private static string DecryptPassword ( byte [ ] encrypted )
939+ private static string DecryptPassword ( byte [ ] encrypted , byte [ ] additionalEntropy )
916940 {
917941 try
918942 {
919- return Encoding . UTF8 . GetString ( System . Security . Cryptography . ProtectedData . Unprotect ( encrypted , null , System . Security . Cryptography . DataProtectionScope . CurrentUser ) ) ;
943+ return Encoding . UTF8 . GetString ( System . Security . Cryptography . ProtectedData . Unprotect ( encrypted , additionalEntropy , System . Security . Cryptography . DataProtectionScope . CurrentUser ) ) ;
920944 }
921945 catch ( System . Security . Cryptography . CryptographicException )
922946 {
0 commit comments