Trying to hash a password - c#

Note: I will not be using salts. Thanks for your advice though!
I'm testing how to hash a password using SHA1 and can't seem to wrap my head around it. My database column is Password char(40) not null.
Here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.Cryptography;
namespace Consumer
{
class Program
{
static void Main(string[] args)
{
string password = "Mypassword";
byte[] data password.tobytearray()???
byte[] result;
SHA1 sha = new SHA1CryptoServiceProvider();
// This is one implementation of the abstract class SHA1.
result = sha.ComputeHash(data);
Console.WriteLine(result.ToString());
Console.ReadLine();
}
}
}

It sounds like you're trying to convert a string into a byte[]. This is done by using one of the Encoding classes.
byte[] data = System.Text.Encoding.Unicode.GetBytes(password);
byte[] data = System.Text.Encoding.ASCII.GetBytes(password);
I'm not sure which is most appropriate for your scenario but I would use Unicode unless I had a specific reason to do otherwise.

To convert a string to a Byte[], use the Encoding class.
Also, result is a Byte[], which doesn't override ToString().
To get a string representation of the byte array, you can call BitConverter.ToString or Convert.ToBase64String.
In a database, you should store the raw byte array directly.

So your correct program would be something like
static void Main(string[] args)
{
string password = "Mypassword";
byte[] data = System.Text.Encoding.ASCII.GetBytes(password);
//or byte[] data = System.Text.Encoding.Unicode.GetBytes(password);
byte[] result;
SHA1 sha = new SHA1CryptoServiceProvider();
// This is one implementation of the abstract class SHA1.
result = sha.ComputeHash(data);
Console.WriteLine(Convert.ToBase64String(result));
Console.ReadLine();
}

Related

How can I get an SHA-256 certificate thumbprint?

How can I get the SHA-256 thumbprint of a certificate?
SHA-256 certificates have two thumbprint, and I am able to retrieve the primary thumbprint, but not SHA-256.
If you want to get a certificate's SHA-256 thumbprint, you have to do some manual work. The built-in Thumbprint property is SHA-1 only.
You have to use a SHA-256 class and compute the hash over the certificate's content:
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
namespace MyNamespace {
class MyClass {
public static String GetSha2Thumbprint(X509Certificate2 cert) {
Byte[] hashBytes;
using (var hasher = new SHA256Managed()) {
hashBytes = hasher.ComputeHash(cert.RawData);
}
return hashBytes.Aggregate(String.Empty, (str, hashByte) => str + hashByte.ToString("x2"));
}
}
}
And you convert this code to an extension method if necessary.
Use:
public static String GetSha2Thumbprint(X509Certificate2 cert)
{
Byte[] hashBytes;
using (var hasher = new SHA256Managed())
{
hashBytes = hasher.ComputeHash(cert.RawData);
}
string result = BitConverter.ToString(hashBytes)
// This will remove all the dashes in between each two characters
.Replace("-", string.Empty).ToLower();
return result;
}
After getting the Hashbytes, you have to do the bit convertion.
This post also helped me: Hashing text with SHA-256 in Windows Forms

MD5 hashing in windowsphone 8

Hay there i'm trying to hash a string to MD5 in windows phone ... but when i call the MD5 class i get the following error
The type or namespace name 'MD5' could not be found (are you missing a
using directive or an assembly reference?)
PS: i have used the System.Security.Cryptography name space
so how can i use the MD5 hash in the windows phone ?
here is my code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
namespace FluoraPin
{
class HASHING
{
public static string GetMd5Hash(MD5 md5Hash, string input)
{
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
// t verify md5 hashing
private bool VerifyMd5Hash(MD5 md5Hash, string input, string hash)
{
// Hash the input.
string hashOfInput = GetMd5Hash(md5Hash, input);
// Create a StringComparer an compare the hashes.
StringComparer comparer = StringComparer.OrdinalIgnoreCase;
if (0 == comparer.Compare(hashOfInput, hash))
{
return true;
}
else
{
return false;
}
}
}
}
I think the answer is right in the error:
The type or namespace name 'MD5' could not be found (are you missing a using directive or an assembly reference?)
MD5 is not a class in the System.Security.Cryptography namespace for Windows Phone. See MSDN's System.Security.Cryptography page for Windows Phone for confirmation.
Contrast this with MSDN's general System.Security.Cryptography page, which lists MD5 as a class in the namespace.
Having said this, you should really use SHA-256 or higher instead of MD5 or SHA-1 hashing.
SHA-256 hashing is available for Windows Phone 7 and 8 through the SHA256Managed class - in the Security.Security.Cryptography namespace you are already using. For an example of how to use SHA256Managed, see an answer to a related SO question.
This person has an implementation of MD5 hashing in C# that can be used for WP8:
http://upadhyayjitesh.blogspot.com/2013/01/windows-phone-md5-hash-conversion.html
You could add Bouncy Castle as a NuGet package to your project. It supports MD5 hashing (and much more encryption algorithms). See its NuGet page for more details. Or its project page "The Legion of the Bouncy Castle"
I haven't tested your solution but I found a solution that works fine for me.
using System.Security.Cryptography;
class MD5Hash
{
public String getHash(String input)
{
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = Encoding.ASCII.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
sb.Append(hash[i].ToString("x2"));
return sb.ToString();
}
public Boolean VerifyHash(String input, String hash)
{
String hashOfInput = getHash(input);
StringComparer comparer = StringComparer.OrdinalIgnoreCase;
if (0 == comparer.Compare(hashOfInput, hash))
return true;
else
return false;
}
}
This will hash your String, no errors at all.
Also, the error you are getting, check that you are not compiling a .Net version that include the text "Client Profile".
I am new to this so If I have got this completely wrong then I'm sorry could you be a bit more specific with you question.

C# RSA Decryption using Bouncy Castle

I have been given a Base64 Encoded encrypted string, which was encrypted in Java using Bouncy Castle. Example Java snippet below:
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, key.getPublic());
byte[] encryptedText = cipher.doFinal("xxxxx|xxxxx".getBytes("UTF-8"));
String encodedText = new BASE64Encoder().encode(encryptedText);
I need to decrypt the resulting string using Bouncy Castle, but in C#
I have been given a code snippet on how to do this in Java, but I can't convert this for C# (reasons is we are building a .net site, and is going to be an iFrame within a Java site. The Java site is going to passing in the RSA Encrypted string to the .NET site). Example Java code to decrypt below:
Cipher cipherDec = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipherDec.init(Cipher.DECRYPT_MODE, key.getPrivate());
byte[] decodedText = new BASE64Decoder().decodeBuffer(encodedText);
byte[] decryptedText = cipherDec.doFinal(decodedText);
String finalValue = new String(decryptedText, "UTF-8");
I have downloaded the examples from http://www.bouncycastle.org/csharp/ but there doesn't seem to be an example of inputting a string value to get encrypted, and it then going though the encrypt/decrypt process.
I have been given values for modulus, public exponent, private expontent, prime P, prime q, prime exponent p, prime exponent q and crt coefficient.
I have seen that I can use the following:
IAsymmetricBlockCipher signer = new Pkcs1Encoding(new RsaEngine());
signer.Init(true, pubParameters);
But the signer object doesn't seem to have the same methods as the Java examples above.
Only method I can use is
ProcessBlock(byte[] inbuf, int inOff, int inLen);
But I can't see how to use this in my context.
Any help here would be most appreciated.
To Help others, the final code to convert is as follows:
RsaKeyParameters privParameters = new RsaPrivateCrtKeyParameters(mod, pubExp, privExp, p, q, pExp, qExp, crtCoef);
RsaKeyParameters pubParameters = new RsaKeyParameters(false, mod, pubExp);
IAsymmetricBlockCipher eng = new Pkcs1Encoding(new RsaEngine());
eng.Init(false, privParameters);
byte[] encdata = System.Convert.FromBase64String("{the enc string}");
encdata = eng.ProcessBlock(encdata, 0, encdata.Length);
string result = Encoding.UTF8.GetString(encdata);
mod, pubExp etc etc are all BigInteger values:
static BigInteger mod = new BigInteger("big int value");
The Following using directives are required:
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Math;
Which can be obtained from the bouncycastle site. http://www.bouncycastle.org/csharp/
Have you tried converting the base 64 string to a byte array and then using the process block method? There may be more to it than that but it's definitely the first step I would take.
Here's an example of how to do this: http://msdn.microsoft.com/en-us/library/system.convert.frombase64string.aspx
I'm not sure I understand why you must use Bouncycastle. The following small code snippet shows and RSA encryption/decryption example using only .NET classes:
using System;
using System.Text;
using System.Security.Cryptography;
namespace RsaForDotNet
{
class Program
{
static void Main(string[] args)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512);
var encrypted_msg = rsa.Encrypt(Encoding.UTF8.GetBytes("Secret Data"), false);
var encoded_msg = Convert.ToBase64String(encrypted_msg);
Console.WriteLine(encoded_msg);
var decoded_msg = Convert.FromBase64String(encoded_msg);
var decrypted_msg = Encoding.UTF8.GetString(rsa.Decrypt(decoded_msg, false));
Console.WriteLine(decrypted_msg);
}
}
}

Replace method doesn't replace dashes to empty string

I'm trying to hash a file using SHA1. The result looks like this: B7-DB-B9-93-E7-2F-6F-EB-6D-CD-CC-A8-DE-D2-F1-01-6E-8A-53-BC
How to I replace dashes to empty string or just remove them?
The code trying to replace the dashes, but it seems like it don't change anything and dashes are still in place.
using (HashAlgorithm hashSHA1 = new SHA1Managed())
using (Stream file = new FileStream(ofdBrowse.FileName, FileMode.Open, FileAccess.Read))
{
byte[] hash = hashSHA1.ComputeHash(file);
txtSHA1.Text = BitConverter.ToString(hash).Replace("-", "");
}
Difference between dash and hyphen?
http://msdn.microsoft.com/en-us/library/3a733s97.aspx
Not really sure. Just my guess in the dark.
The code you've give definitely removes the dashes. Short but complete program to demonstrate that:
using System;
using System.IO;
using System.Security.Cryptography;
class Test
{
static void Main(string[] args)
{
using (HashAlgorithm hashSHA1 = new SHA1Managed())
{
// Actual data doesn't matter
using (Stream data = new MemoryStream())
{
byte[] hash = hashSHA1.ComputeHash(data);
Console.WriteLine(BitConverter.ToString(hash).Replace("-", ""));
}
}
}
}
So, potential cause of your problem:
You're not running the build you think you are
You've got other code which does the hashing but doesn't have the Replace call
You're looking at the wrong bit of the UI :)
It's hard to really guess which of those (or anything else) is the problem, but that code isn't it...

Decoding And Encoding Strings - HardCoded KEY for Symmetric Algorithms

i wrote the below class for encoding and decoding string data (Symmetric Algorithm With One Key):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace MyProject.Classes
{
public static class SymmetricEncryption
{
private const string MyKey = "bla bla bla";
private static string _AlgorithmName;
public static string AlgorithmName
{
get { return _AlgorithmName; }
set { _AlgorithmName = value; }
}
public static string EncryptData(string ClearData)
{
// Convert string ClearData to byte array
byte[] ClearData_byte_Array = Encoding.UTF8.GetBytes(ClearData);
// Now Create The Algorithm
SymmetricAlgorithm Algorithm = SymmetricAlgorithm.Create(AlgorithmName);
Algorithm.Key = Encoding.UTF8.GetBytes(MyKey);
// Encrypt information
MemoryStream Target = new MemoryStream();
// Append IV
Algorithm.GenerateIV();
Target.Write(Algorithm.IV, 0, Algorithm.IV.Length);
// Encrypt Clear Data
CryptoStream cs = new CryptoStream(Target, Algorithm.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(ClearData_byte_Array, 0, ClearData_byte_Array.Length);
cs.FlushFinalBlock();
// Output
byte[] Target_byte_Array = Target.ToArray();
string Target_string = Convert.ToBase64String(Target_byte_Array);
return Target_string;
}
public static string DecryptData(string EncryptedData)
{
byte[] EncryptedData_byte_Array = Convert.FromBase64String(EncryptedData);
// Now Create The Algorithm
SymmetricAlgorithm Algorithm = SymmetricAlgorithm.Create(AlgorithmName);
Algorithm.Key = Encoding.UTF8.GetBytes(MyKey);
// Decrypt information
MemoryStream Target = new MemoryStream();
// Read IV
int ReadPos = 0;
byte[] IV = new byte[Algorithm.IV.Length];
Array.Copy(EncryptedData_byte_Array, IV, IV.Length);
Algorithm.IV = IV;
ReadPos += Algorithm.IV.Length;
// Decrypt Encrypted Data
CryptoStream cs = new CryptoStream(Target, Algorithm.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(EncryptedData_byte_Array, ReadPos, EncryptedData_byte_Array.Length - ReadPos);
cs.FlushFinalBlock();
// Output
byte[] Target_byte_Array = Target.ToArray();
string Target_string = Encoding.UTF8.GetString(Target_byte_Array);
return Target_string;
}
}
}
and usage like below :
protected void Page_Load(object sender, EventArgs e)
{
SymmetricEncryptionUtility.AlgorithmName = "TripleDES";
Response.Write(SymmetricEncryptionUtility.EncryptData("1234-4567-8910-2345"));
}
i have some problem about MyKey -> how can we have hard coded key for Symmetric Algorithms and use it in the upper class ?
the upper codes ERROR is like below :
Server Error in '/' Application.
Specified key is not a valid size for this algorithm.
Description: An unhandled exception occurred during the
execution of the current web request. Please review the stack trace
for more information about the error and where it originated in the
code.
Exception Details:
System.Security.Cryptography.CryptographicException: Specified key is
not a valid size for this algorithm.
how can i fix this error ?
thanks in advance
You can use System.Security.Cryptography.Rfc2898DeriveBytes to securely generate the correct number of bytes for your key based on a string password and byte[] salt:
var helper = new Rfc2898DeriveBytes(password, salt);
algorithm.Key = helper.GetBytes(algorithm.KeySize / 8);
For more information about Rfc2898DeriveBytes and how to use it, check out its page on MSDN.
Read the error and look at the documentation for TripleDES.Key:
This algorithm supports key lengths from 128 bits to 192 bits in increments of 64 bits.
That means for example
private const string MyKey = "bla bla bla blah";
would work.
You didn't ask about this, but I'm not sure creating this class as static is a good idea. If you used it from two different places in your code, it could result in unexpected results, because AlgorithmName is static.
Also, I don't think it makes sense to have a constant key but variable algorithm, especially since different algorithms require keys of different lengths.

Categories