Encrypting a Web.Config value using Microsoft Enterprise Library-J

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

The Data EDRA is execellent in allowing Connection String to be encrypted,
but as yet I could not find any example of how to encrypt the following entry:
<appSettings>
<add key="SpecialPassword" value="aPasswordIwantEncrypted" />
</appSettings>

How could I do this? I already have
securitycryptographyconfiguration.config and the encryption .key file setup
(when I set up my Data EDRA to encrypt connection sting password).
 
I tried using the "Crytography Application Block Quick Start" to encrypt
(getting it the App.Config to point to my own
securityCryptographyconfiguration.config) to encrypt the password into
something like
XVgnl8i//tBn4t3QGMl02TDtqCtMN/0ER/LKe1Burvy/oODQ7N1U9asm2jlOyqUx

I tried to decrypt it in as follows:
String password = System.Text.Encoding.Unicode.GetString(
Cryptographer.DecryptSymmetric("symprovider",
System.Text.Encoding.Unicode.GetBytes
(ConfigurationSettings.AppSettings["ADQuerySysUserPassword"])));

Unfortunately:
the code throws the following exception:
ystem.Security.Cryptography.CryptographicException: PKCS7 padding is invalid
and cannot be removed.
at
System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
at System.Security.Cryptography.CryptoStream.Close()
at
Microsoft.Practices.EnterpriseLibrary.Common.Cryptography.SymmetricCryptographer.Transform(ICryptoTransform transform, Byte[] buffer)
at
Microsoft.Practices.EnterpriseLibrary.Common.Cryptography.SymmetricCryptographer.Decrypt(Byte[] encryptedText)
at
Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.SymmetricAlgorithmProvider.Decrypt(Byte[] ciphertext)
at
Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.Cryptographer.DecryptSymmetric(String
symmetricInstance, Byte[] ciphertext, ConfigurationContext context)

Why? and how do I resolve?
 
I put methods like these in my Utils class. Easy way to encrypt strings or
byte[]:

/// <summary>
/// Use AES to encrypt data string. The output string is the
encrypted bytes as a base64 string.
/// The same password must be used to decrypt the string.
/// </summary>
/// <param name="data">Clear string to encrypt.</param>
/// <param name="password">Password used to encrypt the
string.</param>
/// <returns>Encrypted result as Base64 string.</returns>
public static string EncryptData(string data, string password)
{
if ( data == null )
throw new ArgumentNullException("data");
if ( password == null )
throw new ArgumentNullException("password");

byte[] encBytes = EncryptData(Encoding.UTF8.GetBytes(data),
password, PaddingMode.ISO10126);
return Convert.ToBase64String(encBytes);
}

/// <summary>
/// Decrypt the data string to the original string. The data must
be the base64 string
/// returned from the EncryptData method.
/// </summary>
/// <param name="data">Encrypted data generated from EncryptData
method.</param>
/// <param name="password">Password used to decrypt the
string.</param>
/// <returns>Decrypted string.</returns>
public static string DecryptData(string data, string password)
{
if ( data == null )
throw new ArgumentNullException("data");
if ( password == null )
throw new ArgumentNullException("password");

byte[] encBytes = Convert.FromBase64String(data);
byte[] decBytes = DecryptData(encBytes, password,
PaddingMode.ISO10126);
return Encoding.UTF8.GetString(decBytes);
}

public static byte[] EncryptData(byte[] data, string password,
PaddingMode paddingMode)
{
if ( data == null || data.Length == 0 )
throw new ArgumentNullException("data");
if ( password == null )
throw new ArgumentNullException("password");

PasswordDeriveBytes pdb = new PasswordDeriveBytes(password,
Encoding.UTF8.GetBytes("Salt"));
RijndaelManaged rm = new RijndaelManaged();
rm.Padding = paddingMode;
ICryptoTransform encryptor =
rm.CreateEncryptor(pdb.GetBytes(16), pdb.GetBytes(16));

using ( MemoryStream msEncrypt = new MemoryStream() )
using ( CryptoStream encStream = new CryptoStream(msEncrypt,
encryptor, CryptoStreamMode.Write) )
{
encStream.Write(data, 0, data.Length);
encStream.FlushFinalBlock();
return msEncrypt.ToArray();
}
}

public static byte[] DecryptData(byte[] data, string password,
PaddingMode paddingMode)
{
if ( data == null || data.Length == 0 )
throw new ArgumentNullException("data");
if ( password == null )
throw new ArgumentNullException("password");

PasswordDeriveBytes pdb = new PasswordDeriveBytes(password,
Encoding.UTF8.GetBytes("Salt"));
RijndaelManaged rm = new RijndaelManaged();
rm.Padding = paddingMode;
ICryptoTransform decryptor =
rm.CreateDecryptor(pdb.GetBytes(16), pdb.GetBytes(16));

using ( MemoryStream msDecrypt = new MemoryStream(data) )
using ( CryptoStream csDecrypt = new CryptoStream(msDecrypt,
decryptor, CryptoStreamMode.Read) )
{
// Decrypted bytes will always be less then encrypted bytes,
so len of encrypted data will be big enouph for buffer.
byte[] fromEncrypt = new byte[data.Length];

// Read as many bytes as possible.
int read = csDecrypt.Read(fromEncrypt, 0,
fromEncrypt.Length);
if ( read < fromEncrypt.Length )
{
// Return a byte array of proper size.
byte[] clearBytes = new byte[read];
Buffer.BlockCopy(fromEncrypt, 0, clearBytes, 0, read);
return clearBytes;
}
return fromEncrypt;
}
}

--
William Stacey [MVP]

Patrick said:
I tried using the "Crytography Application Block Quick Start" to encrypt
(getting it the App.Config to point to my own
securityCryptographyconfiguration.config) to encrypt the password into
something like
XVgnl8i//tBn4t3QGMl02TDtqCtMN/0ER/LKe1Burvy/oODQ7N1U9asm2jlOyqUx

I tried to decrypt it in as follows:
String password = System.Text.Encoding.Unicode.GetString(
Cryptographer.DecryptSymmetric("symprovider",
System.Text.Encoding.Unicode.GetBytes
(ConfigurationSettings.AppSettings["ADQuerySysUserPassword"])));

Unfortunately:
the code throws the following exception:
ystem.Security.Cryptography.CryptographicException: PKCS7 padding is
invalid
and cannot be removed.
at
System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[]
inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
at System.Security.Cryptography.CryptoStream.Close()
at
Microsoft.Practices.EnterpriseLibrary.Common.Cryptography.SymmetricCryptographer.Transform(ICryptoTransform
transform, Byte[] buffer)
at
Microsoft.Practices.EnterpriseLibrary.Common.Cryptography.SymmetricCryptographer.Decrypt(Byte[]
encryptedText)
at
Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.SymmetricAlgorithmProvider.Decrypt(Byte[]
ciphertext)
at
Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.Cryptographer.DecryptSymmetric(String
symmetricInstance, Byte[] ciphertext, ConfigurationContext context)

Why? and how do I resolve?

Patrick said:
The Data EDRA is execellent in allowing Connection String to be
encrypted,
but as yet I could not find any example of how to encrypt the following
entry:
<appSettings>
<add key="SpecialPassword" value="aPasswordIwantEncrypted" />
</appSettings>

How could I do this? I already have
securitycryptographyconfiguration.config and the encryption .key file
setup
(when I set up my Data EDRA to encrypt connection sting password).
 
Thanks for the code William, but I am quite interested to know what is wrong
with my original 1 line code. It is simply built on the Microsoft
Cryptography EDRA quick start example!

Something wrong with the getbyte method, perhaps??

William Stacey said:
I put methods like these in my Utils class. Easy way to encrypt strings or
byte[]:

/// <summary>
/// Use AES to encrypt data string. The output string is the
encrypted bytes as a base64 string.
/// The same password must be used to decrypt the string.
/// </summary>
/// <param name="data">Clear string to encrypt.</param>
/// <param name="password">Password used to encrypt the
string.</param>
/// <returns>Encrypted result as Base64 string.</returns>
public static string EncryptData(string data, string password)
{
if ( data == null )
throw new ArgumentNullException("data");
if ( password == null )
throw new ArgumentNullException("password");

byte[] encBytes = EncryptData(Encoding.UTF8.GetBytes(data),
password, PaddingMode.ISO10126);
return Convert.ToBase64String(encBytes);
}

/// <summary>
/// Decrypt the data string to the original string. The data must
be the base64 string
/// returned from the EncryptData method.
/// </summary>
/// <param name="data">Encrypted data generated from EncryptData
method.</param>
/// <param name="password">Password used to decrypt the
string.</param>
/// <returns>Decrypted string.</returns>
public static string DecryptData(string data, string password)
{
if ( data == null )
throw new ArgumentNullException("data");
if ( password == null )
throw new ArgumentNullException("password");

byte[] encBytes = Convert.FromBase64String(data);
byte[] decBytes = DecryptData(encBytes, password,
PaddingMode.ISO10126);
return Encoding.UTF8.GetString(decBytes);
}

public static byte[] EncryptData(byte[] data, string password,
PaddingMode paddingMode)
{
if ( data == null || data.Length == 0 )
throw new ArgumentNullException("data");
if ( password == null )
throw new ArgumentNullException("password");

PasswordDeriveBytes pdb = new PasswordDeriveBytes(password,
Encoding.UTF8.GetBytes("Salt"));
RijndaelManaged rm = new RijndaelManaged();
rm.Padding = paddingMode;
ICryptoTransform encryptor =
rm.CreateEncryptor(pdb.GetBytes(16), pdb.GetBytes(16));

using ( MemoryStream msEncrypt = new MemoryStream() )
using ( CryptoStream encStream = new CryptoStream(msEncrypt,
encryptor, CryptoStreamMode.Write) )
{
encStream.Write(data, 0, data.Length);
encStream.FlushFinalBlock();
return msEncrypt.ToArray();
}
}

public static byte[] DecryptData(byte[] data, string password,
PaddingMode paddingMode)
{
if ( data == null || data.Length == 0 )
throw new ArgumentNullException("data");
if ( password == null )
throw new ArgumentNullException("password");

PasswordDeriveBytes pdb = new PasswordDeriveBytes(password,
Encoding.UTF8.GetBytes("Salt"));
RijndaelManaged rm = new RijndaelManaged();
rm.Padding = paddingMode;
ICryptoTransform decryptor =
rm.CreateDecryptor(pdb.GetBytes(16), pdb.GetBytes(16));

using ( MemoryStream msDecrypt = new MemoryStream(data) )
using ( CryptoStream csDecrypt = new CryptoStream(msDecrypt,
decryptor, CryptoStreamMode.Read) )
{
// Decrypted bytes will always be less then encrypted bytes,
so len of encrypted data will be big enouph for buffer.
byte[] fromEncrypt = new byte[data.Length];

// Read as many bytes as possible.
int read = csDecrypt.Read(fromEncrypt, 0,
fromEncrypt.Length);
if ( read < fromEncrypt.Length )
{
// Return a byte array of proper size.
byte[] clearBytes = new byte[read];
Buffer.BlockCopy(fromEncrypt, 0, clearBytes, 0, read);
return clearBytes;
}
return fromEncrypt;
}
}

--
William Stacey [MVP]

Patrick said:
I tried using the "Crytography Application Block Quick Start" to encrypt
(getting it the App.Config to point to my own
securityCryptographyconfiguration.config) to encrypt the password into
something like
XVgnl8i//tBn4t3QGMl02TDtqCtMN/0ER/LKe1Burvy/oODQ7N1U9asm2jlOyqUx

I tried to decrypt it in as follows:
String password = System.Text.Encoding.Unicode.GetString(
Cryptographer.DecryptSymmetric("symprovider",
System.Text.Encoding.Unicode.GetBytes
(ConfigurationSettings.AppSettings["ADQuerySysUserPassword"])));

Unfortunately:
the code throws the following exception:
ystem.Security.Cryptography.CryptographicException: PKCS7 padding is
invalid
and cannot be removed.
at
System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[]
inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
at System.Security.Cryptography.CryptoStream.Close()
at
Microsoft.Practices.EnterpriseLibrary.Common.Cryptography.SymmetricCryptographer.Transform(ICryptoTransform
transform, Byte[] buffer)
at
Microsoft.Practices.EnterpriseLibrary.Common.Cryptography.SymmetricCryptographer.Decrypt(Byte[]
encryptedText)
at
Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.SymmetricAlgorithmProvider.Decrypt(Byte[]
ciphertext)
at
Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.Cryptographer.DecryptSymmetric(String
symmetricInstance, Byte[] ciphertext, ConfigurationContext context)

Why? and how do I resolve?

Patrick said:
The Data EDRA is execellent in allowing Connection String to be
encrypted,
but as yet I could not find any example of how to encrypt the following
entry:
<appSettings>
<add key="SpecialPassword" value="aPasswordIwantEncrypted" />
</appSettings>

How could I do this? I already have
securitycryptographyconfiguration.config and the encryption .key file
setup
(when I set up my Data EDRA to encrypt connection sting password).
 
Hi Patrick,

As for your original code, I'm wondering on how do you convert the
encrypted bytes into string and store in the web.config? Are you using
System.Text.Encoding or System.Convert.ToBase64string? For converting
bytes to persistent string, we should always use Convert.ToBase64String to
do the job, the Encoding is used to translate for Charset purprose. Here is
the test code I've made on myside, just use the BuildSecureOutput
function to write the encrypted content into a text file and copy them into
configuration file.
Then, we can use PrintSecureItems() function to retrieve the value from
config file.

Hope helps. Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)





static void BuildSecureOutput()
{
NameValueCollection nvc = new NameValueCollection();

nvc.Add("key1","value of key1");
nvc.Add("key2","value of key2");
nvc.Add("key3","value of key3");

using(StreamWriter sw = new StreamWriter("temp.txt", false,
System.Text.Encoding.UTF8))
{
foreach(string key in nvc.Keys)
{
byte[] valueToEncrypt = System.Text.Encoding.UTF8.GetBytes(nvc[key]);
byte[] encryptedContents =
Cryptographer.EncryptSymmetric("RijndaelManaged", valueToEncrypt);

sw.WriteLine(key);
sw.WriteLine(Convert.ToBase64String(encryptedContents));
sw.WriteLine("----------------------------");
}
}
}


static void PrintSecureItems()
{
foreach(string key in
System.Configuration.ConfigurationSettings.AppSettings.Keys)
{
byte[] encryptedBytes =
Convert.FromBase64String(System.Configuration.ConfigurationSettings.AppSetti
ngs[key]);
byte[] bytesToDecode =
Cryptographer.DecryptSymmetric("RijndaelManaged",encryptedBytes);

string decryptedValue =
System.Text.Encoding.UTF8.GetString(bytesToDecode);

Console.WriteLine("key:{0}, value:{1}", key, decryptedValue);
}
}



--------------------
| Thread-Topic: Encrypting a Web.Config value using Microsoft Enterprise
Libra
| thread-index: AcWzlJeZF6BqKOUQSVuR/8cSqP7Hfg==
| X-WBNR-Posting-Host: 198.240.128.75
| From: "=?Utf-8?B?UGF0cmljaw==?=" <[email protected]>
| References: <[email protected]>
<[email protected]>
<[email protected]>
| Subject: Re: Encrypting a Web.Config value using Microsoft Enterprise
Libra
| Date: Wed, 7 Sep 2005 03:12:03 -0700
| Lines: 178
| Message-ID: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="Utf-8"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Content-Class: urn:content-classes:message
| Importance: normal
| Priority: normal
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Newsgroups:
microsoft.public.vsnet.enterprise.tools,microsoft.public.dotnet.framework
| NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.2.250
| Path: TK2MSFTNGXA01.phx.gbl!TK2MSFTNGXA03.phx.gbl
| Xref: TK2MSFTNGXA01.phx.gbl microsoft.public.dotnet.framework:32198
microsoft.public.vsnet.enterprise.tools:1323
| X-Tomcat-NG: microsoft.public.dotnet.framework
|
| Thanks for the code William, but I am quite interested to know what is
wrong
| with my original 1 line code. It is simply built on the Microsoft
| Cryptography EDRA quick start example!
|
| Something wrong with the getbyte method, perhaps??
|
| "William Stacey [MVP]" wrote:
|
| > I put methods like these in my Utils class. Easy way to encrypt
strings or
| > byte[]:
| >
| > /// <summary>
| > /// Use AES to encrypt data string. The output string is the
| > encrypted bytes as a base64 string.
| > /// The same password must be used to decrypt the string.
| > /// </summary>
| > /// <param name="data">Clear string to encrypt.</param>
| > /// <param name="password">Password used to encrypt the
| > string.</param>
| > /// <returns>Encrypted result as Base64 string.</returns>
| > public static string EncryptData(string data, string password)
| > {
| > if ( data == null )
| > throw new ArgumentNullException("data");
| > if ( password == null )
| > throw new ArgumentNullException("password");
| >
| > byte[] encBytes = EncryptData(Encoding.UTF8.GetBytes(data),
| > password, PaddingMode.ISO10126);
| > return Convert.ToBase64String(encBytes);
| > }
| >
| > /// <summary>
| > /// Decrypt the data string to the original string. The data
must
| > be the base64 string
| > /// returned from the EncryptData method.
| > /// </summary>
| > /// <param name="data">Encrypted data generated from
EncryptData
| > method.</param>
| > /// <param name="password">Password used to decrypt the
| > string.</param>
| > /// <returns>Decrypted string.</returns>
| > public static string DecryptData(string data, string password)
| > {
| > if ( data == null )
| > throw new ArgumentNullException("data");
| > if ( password == null )
| > throw new ArgumentNullException("password");
| >
| > byte[] encBytes = Convert.FromBase64String(data);
| > byte[] decBytes = DecryptData(encBytes, password,
| > PaddingMode.ISO10126);
| > return Encoding.UTF8.GetString(decBytes);
| > }
| >
| > public static byte[] EncryptData(byte[] data, string password,
| > PaddingMode paddingMode)
| > {
| > if ( data == null || data.Length == 0 )
| > throw new ArgumentNullException("data");
| > if ( password == null )
| > throw new ArgumentNullException("password");
| >
| > PasswordDeriveBytes pdb = new PasswordDeriveBytes(password,
| > Encoding.UTF8.GetBytes("Salt"));
| > RijndaelManaged rm = new RijndaelManaged();
| > rm.Padding = paddingMode;
| > ICryptoTransform encryptor =
| > rm.CreateEncryptor(pdb.GetBytes(16), pdb.GetBytes(16));
| >
| > using ( MemoryStream msEncrypt = new MemoryStream() )
| > using ( CryptoStream encStream = new
CryptoStream(msEncrypt,
| > encryptor, CryptoStreamMode.Write) )
| > {
| > encStream.Write(data, 0, data.Length);
| > encStream.FlushFinalBlock();
| > return msEncrypt.ToArray();
| > }
| > }
| >
| > public static byte[] DecryptData(byte[] data, string password,
| > PaddingMode paddingMode)
| > {
| > if ( data == null || data.Length == 0 )
| > throw new ArgumentNullException("data");
| > if ( password == null )
| > throw new ArgumentNullException("password");
| >
| > PasswordDeriveBytes pdb = new PasswordDeriveBytes(password,
| > Encoding.UTF8.GetBytes("Salt"));
| > RijndaelManaged rm = new RijndaelManaged();
| > rm.Padding = paddingMode;
| > ICryptoTransform decryptor =
| > rm.CreateDecryptor(pdb.GetBytes(16), pdb.GetBytes(16));
| >
| > using ( MemoryStream msDecrypt = new MemoryStream(data) )
| > using ( CryptoStream csDecrypt = new
CryptoStream(msDecrypt,
| > decryptor, CryptoStreamMode.Read) )
| > {
| > // Decrypted bytes will always be less then encrypted
bytes,
| > so len of encrypted data will be big enouph for buffer.
| > byte[] fromEncrypt = new byte[data.Length];
| >
| > // Read as many bytes as possible.
| > int read = csDecrypt.Read(fromEncrypt, 0,
| > fromEncrypt.Length);
| > if ( read < fromEncrypt.Length )
| > {
| > // Return a byte array of proper size.
| > byte[] clearBytes = new byte[read];
| > Buffer.BlockCopy(fromEncrypt, 0, clearBytes, 0,
read);
| > return clearBytes;
| > }
| > return fromEncrypt;
| > }
| > }
| >
| > --
| > William Stacey [MVP]
| >
| > | > >I tried using the "Crytography Application Block Quick Start" to
encrypt
| > > (getting it the App.Config to point to my own
| > > securityCryptographyconfiguration.config) to encrypt the password into
| > > something like
| > > XVgnl8i//tBn4t3QGMl02TDtqCtMN/0ER/LKe1Burvy/oODQ7N1U9asm2jlOyqUx
| > >
| > > I tried to decrypt it in as follows:
| > > String password = System.Text.Encoding.Unicode.GetString(
| > >
Cryptographer.DecryptSymmetric("symprovider",
| > > System.Text.Encoding.Unicode.GetBytes
| > > (ConfigurationSettings.AppSettings["ADQuerySysUserPassword"])));
| > >
| > > Unfortunately:
| > > the code throws the following exception:
| > > ystem.Security.Cryptography.CryptographicException: PKCS7 padding is
| > > invalid
| > > and cannot be removed.
| > > at
| > >
System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(By
te[]
| > > inputBuffer, Int32 inputOffset, Int32 inputCount)
| > > at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
| > > at System.Security.Cryptography.CryptoStream.Close()
| > > at
| > >
Microsoft.Practices.EnterpriseLibrary.Common.Cryptography.SymmetricCryptogra
pher.Transform(ICryptoTransform
| > > transform, Byte[] buffer)
| > > at
| > >
Microsoft.Practices.EnterpriseLibrary.Common.Cryptography.SymmetricCryptogra
pher.Decrypt(Byte[]
| > > encryptedText)
| > > at
| > >
Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.SymmetricAlgorit
hmProvider.Decrypt(Byte[]
| > > ciphertext)
| > > at
| > >
Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.Cryptographer.De
cryptSymmetric(String
| > > symmetricInstance, Byte[] ciphertext, ConfigurationContext context)
| > >
| > > Why? and how do I resolve?
| > >
| > > "Patrick" wrote:
| > >
| > >> The Data EDRA is execellent in allowing Connection String to be
| > >> encrypted,
| > >> but as yet I could not find any example of how to encrypt the
following
| > >> entry:
| > >> <appSettings>
| > >> <add key="SpecialPassword" value="aPasswordIwantEncrypted" />
| > >> </appSettings>
| > >>
| > >> How could I do this? I already have
| > >> securitycryptographyconfiguration.config and the encryption .key
file
| > >> setup
| > >> (when I set up my Data EDRA to encrypt connection sting password).
| > >>
| > >>
| >
| >
| >
|
 
Back
Top