For an application purpose, I want to store an complete content of the email (string) in the dictionary.
[I know that this is what every hash function provides but wanted to explicitly state that the hash for the same string should always be the same]
Since its not for cryptographic reason and only for storing in dictionary. Can any one please suggest a good hashing function that is available in .Net. My concern is that the email string can be pretty big and i want my hash function to support the big string and not cause frequent collision. I am looking for storing around 500 entries.
Please note i dont want to write my own hash funciton but leverage an existing availaible hash function in .Net
You may consider to use HashAlgorithm.ComputeHash.
Here is an example which is provided with this function:
using System;
using System.Security.Cryptography;
using System.Text;
public class Program
{
public static void Main()
{
string source = "Hello World!";
using (SHA256 sha256Hash = SHA256.Create())
{
string hash = GetHash(sha256Hash, source);
Console.WriteLine($"The SHA256 hash of {source} is: {hash}.");
Console.WriteLine("Verifying the hash...");
if (VerifyHash(sha256Hash, source, hash))
{
Console.WriteLine("The hashes are the same.");
}
else
{
Console.WriteLine("The hashes are not same.");
}
}
}
private static string GetHash(HashAlgorithm hashAlgorithm, string input)
{
// Convert the input string to a byte array and compute the hash.
byte[] data = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(input));
// Create a new Stringbuilder to collect the bytes
// and create a string.
var 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();
}
// Verify a hash against a string.
private static bool VerifyHash(HashAlgorithm hashAlgorithm, string input, string hash)
{
// Hash the input.
var hashOfInput = GetHash(hashAlgorithm, input);
// Create a StringComparer an compare the hashes.
StringComparer comparer = StringComparer.OrdinalIgnoreCase;
return comparer.Compare(hashOfInput, hash) == 0;
}
}
I hope it helps 😊
Related
In my program i wan to run my InputPass.text through:
static string Hash(string input)
{
using (SHA1Managed sha1 = new SHA1Managed())
{
var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(input));
var sb = new StringBuilder(hash.Length * 2);
foreach (byte b in hash)
{
sb.Append(b.ToString("X2"));
}
return sb.ToString();
}
}
How do i put text into it and grab out the result to be put into my string hash pass. im having trouble understanding its process and would like to understand it as well. The hashed pass is what i am looking to instantly hash to be stored in an xml document for a local users file.
Maybe the parameter you give the function as parameter is null or empty.
You can debug it and look at the variable or you can check with
string.IsNullOrEmpty(<your_string>)
I use SHA512Managed class for coding user password string. I initually create etalon string coded in the folowing way:
Convert password string (for example "Johnson_#1") to byte array;
Get hash value of this byte array using SHA512Managed.ComputeHash
method. As you know, hash value gotten from SHA512Managed.ComputeHash(byte[])
method is byte array too.
Then (in program loop) I convert this hash byte array to string in the following way:
System.Text.StringBuilder sBuilder = new System.Text.StringBuilder();
for (int i = 0; i < passwordСache.Length; i++)
{
sBuilder.Append(passwordСache[i].ToString("x2"));
}
string passwordCacheString = sBuilder.ToString();
where the passwordСache is hash byte array and passwordCacheString is result string.
Finally, I store result string in MS SQL Server database table as etalon string.
The matter is in the folowing: If I periodically call SHA512Managed.ComputeHash(byte[]) method and each time pass to it the same byte array as input parameter (for example obtained from "Johnson_#1" string), then the content of returned hash byte array will differs from time to time.
So, if I convert such hash byte array to string (as I showed above) and compare this string to etalon string that is in database table, then the content of this string will differ from content of etalon string though the same string ("Johnson_#1") underlies.
Better defined the question
My question is: Is there a way of determining that two compared SHA512Managed hash byte arrays with different content were created on the base of the same string? Yuor help will be appreciated highly.
As xanatos mentioned in his comments, hash functions must be deterministic.
That is for the same input, you'll get the same hash output.
Try it for yourself:
SHA512Managed sha512Managed = new SHA512Managed();
for (int i = 0; i < 1000; i++) {
var input = Guid.NewGuid().ToString();
byte[] data = sha512Managed.ComputeHash(Encoding.UTF8.GetBytes(input));
byte[] data2 = sha512Managed.ComputeHash(Encoding.UTF8.GetBytes(input));
if (Encoding.UTF8.GetString(data) != Encoding.UTF8.GetString(data2)) {
throw new InvalidOperationException("Hash functions as we know them are useless");
}
}
I am making a WPF C# application, and from what I have read on other threads on many forums, the code of a C# application can be rebuilt from a .exe file.
Now in my code there is a string containing the login data of a database, and I am also considering to use a simmetric cryptography to send encrypted passwords to the db, so the code of the client will contain the simmetric key, but this issue would make vain all my efforts to make a secure application.
How can this security issue be solved, especially in my case?
The solution is to have the passwords hashed in the database and not encrypted. Hash is a one way transformation of the string and cannot be reversed.
Then you hash the input value the user supplies and compare it with what you have in the database. If the hash matches they can log in otherwise an error is displayed.
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();
}
// Verify a hash against a string.
static 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;
}
}
From here MSDN site
I want to generate a API key for new clients that want to use any of my API services.
because I'm using a open API service i don't want to use authentication only identify the client usage by the API key
I tried to use this code
public static string GetAPIKey()
{
string sig = string.Empty;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
var ex = rsa.ExportParameters(true);
sig = Convert.ToBase64String(ex.DQ);
sig = sig
.Replace("+", "")
.Replace("/", "")
.TrimEnd('=');
}
return sig.Substring(0, 64);
}
In my tests i do get a random 64 length string, but something not feeling right with the method usage. proberly because of the RSACryptoServiceProvider usage, especially when i try to generate the DQ property
Do you know any better implementation of generating a random 64 string?
If you do not want to use a GUID you can use the standard Random class in C#.
private static readonly Random Random = new Random();
public static string GetApiKey()
{
var bytes = new byte[48];
Random.NextBytes(bytes);
var result = Convert.ToBase64String(bytes);
return result;
}
Since 48 bytes will map to 64 characters in Base64, this gives you 64 random characters. It does not guarantee uniqueness however.
Why not just use a GUID?
Use it twice to generate a 64 character string, which is completely random and unique.
I've tried every example I can find on the web but I cannot get my .NET code to produce the same MD5 Hash results from my VB6 app.
The VB6 app produces identical results to this site:
http://www.functions-online.com/md5.html
But I cannot get the same results for the same input in C# (using either the MD5.ComputeHash method or the FormsAuthentication encryption method)
Please help!!!!
As requested, here is some code. This is pulled straight from MSDN:
public string hashString(string input)
{
// Create a new instance of the MD5CryptoServiceProvider object.
MD5 md5Hasher = MD5.Create();
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hasher.ComputeHash(Encoding.Default.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();
}
My test string is:
QWERTY123TEST
The results from this code is:
8c31a947080131edeaf847eb7c6fcad5
The result from Test MD5 is:
f6ef5dc04609664c2875895d7da34eb9
Note: The result from the TestMD5 is what I am expecting
Note: I've been really, really stupid, sorry - just realised I had the wrong input. As soon as I hard-coded it, it worked. Thanks for the help
This is a C# MD5 method that i know works, i have used it to authenticate via different web restful APIs
public static string GetMD5Hash(string input)
{
System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] bs = System.Text.Encoding.UTF8.GetBytes(input);
bs = x.ComputeHash(bs);
System.Text.StringBuilder s = new System.Text.StringBuilder();
foreach (byte b in bs)
{
s.Append(b.ToString("x2").ToLower());
}
return s.ToString();
}
What makes the "functions-online" site (http://www.functions-online.com/md5.html) an authority on MD5? For me, it works OK only for ISO-8859-1. But when I try pasting anything other than ISO-8859-1 into it, it returns the same MD5 hash. Try Cyrillic capital B by itself, code point 0x412. Or try Han Chinese symbol for water, code point 0x98A8.
As far as I know, the posted C# applet is correct.