Skip to content

Commit 5eb8820

Browse files
author
Erwin Koek
committed
Add support for additional entropy for encrypting the password
1 parent 0daca3e commit 5eb8820

File tree

1 file changed

+34
-10
lines changed

1 file changed

+34
-10
lines changed

src/Ookii.Dialogs.Wpf/CredentialDialog.cs

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)