@@ -52,6 +52,7 @@ public partial class CredentialDialog : Component
52
52
{
53
53
private string _confirmTarget ;
54
54
private NetworkCredential _credentials = new NetworkCredential ( ) ;
55
+ private byte [ ] _additionalEntropy ;
55
56
private bool _isSaveChecked ;
56
57
private string _target ;
57
58
@@ -163,6 +164,27 @@ private set
163
164
}
164
165
}
165
166
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
+
166
188
/// <summary>
167
189
/// Gets the user-specified user name and password in a <see cref="NetworkCredential"/> object.
168
190
/// </summary>
@@ -551,7 +573,7 @@ public void ConfirmCredentials(bool confirm)
551
573
}
552
574
}
553
575
554
- StoreCredential ( Target , Credentials ) ;
576
+ StoreCredential ( Target , Credentials , AdditionalEntropy ) ;
555
577
}
556
578
}
557
579
@@ -560,6 +582,7 @@ public void ConfirmCredentials(bool confirm)
560
582
/// </summary>
561
583
/// <param name="target">The target name for the credentials.</param>
562
584
/// <param name="credential">The credentials to store.</param>
585
+ /// <param name="additionalEntropy">Additional entropy for encrypting the password.</param>
563
586
/// <exception cref="ArgumentNullException">
564
587
/// <para>
565
588
/// <paramref name="target"/> is <see langword="null" />.
@@ -585,7 +608,7 @@ public void ConfirmCredentials(bool confirm)
585
608
/// form "Company_ApplicationName_www.example.com".
586
609
/// </para>
587
610
/// </remarks>
588
- public static void StoreCredential ( string target , NetworkCredential credential )
611
+ public static void StoreCredential ( string target , NetworkCredential credential , byte [ ] additionalEntropy = null )
589
612
{
590
613
if ( target == null )
591
614
throw new ArgumentNullException ( "target" ) ;
@@ -598,7 +621,7 @@ public static void StoreCredential(string target, NetworkCredential credential)
598
621
c . UserName = credential . UserName ;
599
622
c . TargetName = target ;
600
623
c . Persist = NativeMethods . CredPersist . Enterprise ;
601
- byte [ ] encryptedPassword = EncryptPassword ( credential . Password ) ;
624
+ byte [ ] encryptedPassword = EncryptPassword ( credential . Password , additionalEntropy ) ;
602
625
c . CredentialBlob = System . Runtime . InteropServices . Marshal . AllocHGlobal ( encryptedPassword . Length ) ;
603
626
try
604
627
{
@@ -618,6 +641,7 @@ public static void StoreCredential(string target, NetworkCredential credential)
618
641
/// Retrieves credentials for the specified target from the operating system's credential store for the current user.
619
642
/// </summary>
620
643
/// <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>
621
645
/// <returns>The credentials if they were found; otherwise, <see langword="null" />.</returns>
622
646
/// <remarks>
623
647
/// <para>
@@ -632,7 +656,7 @@ public static void StoreCredential(string target, NetworkCredential credential)
632
656
/// <exception cref="ArgumentNullException"><paramref name="target"/> is <see langword="null" />.</exception>
633
657
/// <exception cref="ArgumentException"><paramref name="target"/> is an empty string ("").</exception>
634
658
/// <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 )
636
660
{
637
661
if ( target == null )
638
662
throw new ArgumentNullException ( "target" ) ;
@@ -653,7 +677,7 @@ public static NetworkCredential RetrieveCredential(string target)
653
677
NativeMethods . CREDENTIAL c = ( NativeMethods . CREDENTIAL ) System . Runtime . InteropServices . Marshal . PtrToStructure ( credential , typeof ( NativeMethods . CREDENTIAL ) ) ;
654
678
byte [ ] encryptedPassword = new byte [ c . CredentialBlobSize ] ;
655
679
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 ) ) ;
657
681
}
658
682
finally
659
683
{
@@ -896,7 +920,7 @@ private NativeMethods.CREDUI_INFO CreateCredUIInfo(IntPtr owner, bool downlevelT
896
920
897
921
private bool RetrieveCredentials ( )
898
922
{
899
- NetworkCredential credential = RetrieveCredential ( Target ) ;
923
+ NetworkCredential credential = RetrieveCredential ( Target , AdditionalEntropy ) ;
900
924
if ( credential != null )
901
925
{
902
926
UserName = credential . UserName ;
@@ -906,17 +930,17 @@ private bool RetrieveCredentials()
906
930
return false ;
907
931
}
908
932
909
- private static byte [ ] EncryptPassword ( string password )
933
+ private static byte [ ] EncryptPassword ( string password , byte [ ] additionalEntropy )
910
934
{
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 ) ;
912
936
return protectedData ;
913
937
}
914
938
915
- private static string DecryptPassword ( byte [ ] encrypted )
939
+ private static string DecryptPassword ( byte [ ] encrypted , byte [ ] additionalEntropy )
916
940
{
917
941
try
918
942
{
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 ) ) ;
920
944
}
921
945
catch ( System . Security . Cryptography . CryptographicException )
922
946
{
0 commit comments