Reputation: 31
Trying to simulate a file upload using HTTPWebRequest. The client side is using Md5.js from this developer MD5.js
In my C# code I am generating the encyptered string as such
public string PasswordHash(string password, string Key)
{
ASCIIEncoding encoding = new ASCIIEncoding();
HMACMD5 hmacmd = new HMACMD5(encoding.GetBytes(Key));
byte[] bytes = encoding.GetBytes(password);
byte[] byteBuffer= hmacmd.ComputeHash(bytes);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < buffer3.Length; i++)
{
builder.Append(byteBuffer[i].ToString("x2"));
}
return builder.ToString().ToLower();
}
The function from MD5.js being used is next:
function hex_hmac_md5(k, d) {
return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)));
}
Using fiddler I captured the key when logging using IE as well as the encrypted password. The password generated by my code using C# and same key does not match that of what the JavaScript method produces. what can I be missing?
C# pwd:5d2b9c906608d8381cef4c24ff045be7
pwd as generated by web site using .js and captured using FIDDLER: f79a31f85da55aa0e3aca07e06568709
Upvotes: 3
Views: 909
Reputation: 325
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.Web.Helpers;
using System.IO;
namespace Utility
{
public class PasswordManager
{
#region [ Public Methods ]
/// <summary>
/// AES 256 Encryption
/// </summary>
/// <param name="inputText">string InputText</param>
/// <returns>string EncryptedText</returns>
public string Encryption(string InputText)
{
string EncryptedText = string.Empty;
try
{
if (string.IsNullOrEmpty(InputText))
{
throw new ArgumentException(Keys.NullInputEncryptionString);
}
else
{
EncryptedText = EncryptToBase64(InputText);
}
}
catch (Exception ExceptionObject)
{
throw;
}
return EncryptedText;
}
/// <summary>
/// AES 256 Decryption
/// </summary>
/// <param name="encryptedText">string encryptedText</param>
/// <returns>string DecryptedText</returns>
public string Decryption(string EncryptedText)
{
string DecryptedText = string.Empty;
try
{
if (string.IsNullOrEmpty(EncryptedText))
{
throw new ArgumentException(Keys.NullInputDecryptionString);
}
DecryptedText = DecryptFromBase64(EncryptedText);
}
catch (Exception ExceptionObject)
{
throw;
}
return DecryptedText;
}
#endregion
#region [ Private Methods ]
/// <summary>
/// Encrypt string with AES-256 by using password.
/// </summary>
/// <param name="password">Password string.</param>
/// <param name="s">String to encrypt.</param>
/// <returns>Encrypted Base64 string.</returns>
private static string EncryptToBase64(string InputText)
{
// Turn input strings into a byte array.
byte[] InputByteArray = System.Text.Encoding.Unicode.GetBytes(InputText);
// Get encrypted bytes.
byte[] EncryptedBytes = EncryptValue(InputByteArray);
// Convert encrypted data into a base64-encoded string.
string Base64String = System.Convert.ToBase64String(EncryptedBytes);
// Return encrypted string.
return Base64String;
}
/// <summary>
/// Decrypt string with AES-256 by using password key.
/// </summary>
/// <param name="password">String password.</param>
/// <param name="base64String">Encrypted Base64 string.</param>
/// <returns>Decrypted string.</returns>
private static string DecryptFromBase64(string EncryptedText)
{
// Convert Base64 string into a byte array.
byte[] EncryptedBytes = System.Convert.FromBase64String(EncryptedText);
byte[] DecryptedBytes = DecryptValue(EncryptedBytes);
// Convert decrypted data into a string.
string OutputString = System.Text.Encoding.Unicode.GetString(DecryptedBytes, 0, DecryptedBytes.Length);
// Return decrypted string.
return OutputString;
}
/// <summary>
/// Encrypt string with AES-256 by using password.
/// </summary>
/// <param name="password">String password.</param>
/// <param name="bytes">Bytes to encrypt.</param>
/// <returns>Encrypted bytes.</returns>
private static byte[] EncryptValue(byte[] Bytes)
{
// Create a encryptor.
ICryptoTransform Encryptor = GetTransform(true);
// Return encrypted bytes.
return CipherStreamWrite(Encryptor, Bytes);
}
/// <summary>
/// Decrypt string with AES-256 by using password key.
/// </summary>
/// <param name="password">String password.</param>
/// <param name="encryptedBytes">Encrypted bytes.</param>
/// <returns>Decrypted bytes.</returns>
private static byte[] DecryptValue(byte[] Bytes)
{
// Create a encryptor.
ICryptoTransform Decryptor = GetTransform(false);
// Return encrypted bytes.
return CipherStreamWrite(Decryptor, Bytes);
}
/// <summary>
/// Cryptographic transformation
/// </summary>
/// <param name="password"></param>
/// <param name="encrypt"></param>
/// <returns></returns>
private static ICryptoTransform GetTransform(bool Encrypt)
{
// Create an instance of the Rihndael class.
RijndaelManaged Cipher = new System.Security.Cryptography.RijndaelManaged();
// Calculate salt to make it harder to guess key by using a dictionary attack.
byte[] Salt = SaltFromPassword();
// Generate Secret Key from the password and salt.
// Note: Set number of iterations to 10 in order for JavaScript example to work faster.
Rfc2898DeriveBytes SecretKey = new System.Security.Cryptography.Rfc2898DeriveBytes(Keys.KEY, Salt, 10);
// Create a encryptor from the existing SecretKey bytes by using
// 32 bytes (256 bits) for the secret key and
// 16 bytes (128 bits) for the initialization vector (IV).
byte[] SecretKeyBytes = SecretKey.GetBytes(32);
byte[] InitializationVectorBytes = SecretKey.GetBytes(16);
ICryptoTransform Cryptor = null;
if (Encrypt)
{
Cryptor = Cipher.CreateEncryptor(SecretKeyBytes, InitializationVectorBytes);
}
else
{
Cryptor = Cipher.CreateDecryptor(SecretKeyBytes, InitializationVectorBytes);
}
return Cryptor;
}
/// <summary>
/// Encrypt/Decrypt with Write method.
/// </summary>
/// <param name="cryptor"></param>
/// <param name="input"></param>
/// <returns></returns>
private static byte[] CipherStreamWrite(ICryptoTransform Cryptor, byte[] InputBytes)
{
try
{
byte[] InputBuffer = new byte[InputBytes.Length];
// Copy data bytes to input buffer.
Buffer.BlockCopy(InputBytes, 0, InputBuffer, 0, InputBuffer.Length);
// Create a MemoryStream to hold the output bytes.
MemoryStream MemoryStream = new MemoryStream();
// Create a CryptoStream through which we are going to be processing our data.
CryptoStreamMode CryptoStreamMode;
CryptoStreamMode = CryptoStreamMode.Write;
CryptoStream CryptoStream;
CryptoStream = new CryptoStream(MemoryStream, Cryptor, CryptoStreamMode);
// Start the crypting process.
CryptoStream.Write(InputBuffer, 0, InputBuffer.Length);
// Finish crypting.
CryptoStream.FlushFinalBlock();
// Convert data from a memoryStream into a byte array.
byte[] OutputBuffer = MemoryStream.ToArray();
// Close both streams.
MemoryStream.Close();
CryptoStream.Close();
return OutputBuffer;
}
catch (Exception ExceptionObject)
{
throw;
}
}
/// <summary>
/// Generate salt from password.
/// </summary>
/// <param name="password">Password string.</param>
/// <returns>Salt bytes.</returns>
private static byte[] SaltFromPassword()
{
try
{
byte[] KeyBytes = System.Text.Encoding.UTF8.GetBytes(Keys.KEY);
HMACSHA1 HashFunctionSha1;
HashFunctionSha1 = new HMACSHA1(KeyBytes);
byte[] Salt = HashFunctionSha1.ComputeHash(KeyBytes);
return Salt;
}
catch (Exception)
{
throw;
}
}
#endregion
}
static class Keys
{
#region [ Private Fields ]
private static string nullInputEncryptionString = "Encryption Failed : Invalid / Empty Input String";
private static string nullInputDecryptionString = "Decryption Failed : Invalid / Empty Input String";
private static string key = "Test@2013Rebuild$Encrypt";
#endregion
#region [ public properties ]
public static string NullInputEncryptionString { get { return nullInputEncryptionString; } }
public static string NullInputDecryptionString { get { return nullInputDecryptionString; } }
public static string KEY { get { return key; } }
#endregion
}
}
When Calling from your Servics
/// <summary>
/// Validate the password hash
/// </summary>
/// <param name="model"></param>
/// <param name="entity"></param>
public void ValidatePasswordHashForUser(UserModels model, string entity)
{
string passwordHash = string.Empty;
try
{
passwordHash = ValidatePasswordWithHash(model.Password, _objUserModel.PasswordHash);
model.PasswordHash = passwordHash;
}
catch (Exception ex)
{
Logger.Error("Exception from GetSaltAndHashForUser(): " + ex.Message);
}
}
/// <summary>
/// Validate password hash
/// </summary>
/// <param name="password"></param>
/// <param name="passwordHash"></param>
/// <returns></returns>
public string ValidatePasswordWithHash(string password, string passwordHash)
{
string passwordHashGenerated = string.Empty;
passwordHashGenerated = _pwdManager.Encryption(password);
return passwordHashGenerated;
}
/// <summary>
/// Generate password hash
/// </summary>
/// <param name="password"></param>
/// <returns></returns>
public string GeneratePasswordHash(string password)
{
string passwordHash = string.Empty;
if (!String.IsNullOrEmpty(password))
{
passwordHash = _pwdManager.Encryption(password);
}
return passwordHash;
}
Upvotes: 0
Reputation: 467
Name Space :
using System.Web.Security;
using System.Security.Cryptography;
using System.Security.Authentication;
using System.Data;
CODE USING "MD5" :
string pass = FormsAuthentication.HashPasswordForStoringInConfigFile(TextBox2.Text,"MD5");
cmd = new SqlCommand("select * from tblname where email = '"+TextBox1.Text+"' and pass ='"+pass+"'");
Upvotes: 1
Reputation: 50672
Are you sure MD5.js is also using ASCII encoding? It looks like it is using UTF8
Upvotes: 1