For example the password is "Hello World", How can I make it return to a RIPEMD160 Hash String? It is supposed to return a string: "a830d7beb04eb7549ce990fb7dc962e499a27230". I searched already the internet for the answer to my question but instead of a string the code is about encrypting a file to RIPEMD160.
OK I already know the solution to the problem. Convert the string to a byte, pass it to RIPEMD160 function, Create a StringBuilder and pass the returned byte of the RIPEMD160 function, Convert the returned StringBuilder to string and once again convert it to lower case. I created a function for it. Here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
namespace Password
{
class Program
{
static void Main(string[] args)
{
string thePassword = "Hello World";
string theHash = getHash(thePassword);
Console.WriteLine("String: " + thePassword);
Console.WriteLine("Encrypted Hash: " + theHash);
Console.ReadKey(true);
}
static string getHash(string password)
{
// create a ripemd160 object
RIPEMD160 r160 = RIPEMD160Managed.Create();
// convert the string to byte
byte[] myByte = System.Text.Encoding.ASCII.GetBytes(password);
// compute the byte to RIPEMD160 hash
byte[] encrypted = r160.ComputeHash(myByte);
// create a new StringBuilder process the hash byte
StringBuilder sb = new StringBuilder();
for (int i = 0; i < encrypted.Length; i++)
{
sb.Append(encrypted[i].ToString("X2"));
}
// convert the StringBuilder to String and convert it to lower case and return it.
return sb.ToString().ToLower();
}
}
}
Related
I want to hash given byte[] array with using SHA1 Algorithm with the use of SHA1Managed.
The byte[] hash will come from unit test.
Expected hash is 0d71ee4472658cd5874c5578410a9d8611fc9aef (case sensitive).
How can I achieve this?
public string Hash(byte [] temp)
{
using (SHA1Managed sha1 = new SHA1Managed())
{
}
}
For those who want a "standard" text formatting of the hash, you can use something like the following:
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)
{
// can be "x2" if you want lowercase
sb.Append(b.ToString("X2"));
}
return sb.ToString();
}
}
This will produce a hash like 0C2E99D0949684278C30B9369B82638E1CEAD415.
Or for a code golfed version:
static string Hash(string input)
{
var hash = new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(input));
return string.Concat(hash.Select(b => b.ToString("x2")));
}
For .Net 5 and above, the built-in Convert.ToHexString gives a nice solution with no compromises:
static string Hash(string input)
{
using var sha1 = SHA1.Create();
return Convert.ToHexString(sha1.ComputeHash(Encoding.UTF8.GetBytes(input)));
}
public string Hash(byte [] temp)
{
using (SHA1Managed sha1 = new SHA1Managed())
{
var hash = sha1.ComputeHash(temp);
return Convert.ToBase64String(hash);
}
}
EDIT:
You could also specify the encoding when converting the byte array to string as follows:
return System.Text.Encoding.UTF8.GetString(hash);
or
return System.Text.Encoding.Unicode.GetString(hash);
This is what I went with. For those of you who want to optimize, check out https://stackoverflow.com/a/624379/991863.
public static string Hash(string stringToHash)
{
using (var sha1 = new SHA1Managed())
{
return BitConverter.ToString(sha1.ComputeHash(Encoding.UTF8.GetBytes(stringToHash)));
}
}
You can "compute the value for the specified byte array" using ComputeHash:
var hash = sha1.ComputeHash(temp);
If you want to analyse the result in string representation, then you will need to format the bytes using the {0:X2} format specifier.
Fastest way is this :
public static string GetHash(string input)
{
return string.Join("", (new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(input))).Select(x => x.ToString("X2")).ToArray());
}
For Small character output use x2 in replace of of X2
I'll throw my hat in here:
(as part of a static class, as this snippet is two extensions)
//hex encoding of the hash, in uppercase.
public static string Sha1Hash (this string str)
{
byte[] data = UTF8Encoding.UTF8.GetBytes (str);
data = data.Sha1Hash ();
return BitConverter.ToString (data).Replace ("-", "");
}
// Do the actual hashing
public static byte[] Sha1Hash (this byte[] data)
{
using (SHA1Managed sha1 = new SHA1Managed ()) {
return sha1.ComputeHash (data);
}
I have this C# code:
public static string Encript(string strData)
{
string hashValue = HashData(strData);
string hexHashData = ConvertStringToHex(hashValue);
return hexHashData;
}
public static string HashData(string textToBeEncripted)
{
//Convert the string to a byte array
Byte[] byteDataToHash = System.Text.Encoding.Unicode.GetBytes(textToBeEncripted);
//Compute the MD5 hash algorithm
Byte[] byteHashValue = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(byteDataToHash);
return System.Text.Encoding.Unicode.GetString(byteHashValue);
}
public static string ConvertStringToHex(string asciiString)
{
string hex = "";
foreach (char c in asciiString)
{
int tmp = c;
hex += String.Format("{0:x2}", (uint) System.Convert.ToUInt32(tmp.ToString()));
}
return hex;
}
Here you can see an online version.As you can see for the string "test" I get the output "5c82e9e41c7599f790ef1d774b7e6bf"
And this is what I tried on php side
$a = "test";
$a = mb_convert_encoding($a, "UTF-16LE");
$a = md5($a);
echo $a;
But the value of the php code is "c8059e2ec7419f590e79d7f1b774bfe6".Why is not working?
Edit:Looks like the C# code is incorrect and needs to be replaced
The correct MD5 hash for 'test' is '098f6bcd4621d373cade4e832627b4f6' in PHP.
I tested it with this code in C#
public static string CreateMD5(string input)
{
// Use input string to calculate MD5 hash
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
// Convert the byte array to hexadecimal string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("X2"));
}
return sb.ToString();
}
}
It will generate the same hash as PHP will, without the 'convert encoding' method you are using.
I believe converting the encoding is what is giving you a different answer, try it without
$a = mb_convert_encoding($a, "UTF-16LE");
The problem is that you are converting the result incorrectly in your C# code. If you put a breakpoint in the code after you call ComputeHash, and examine the value of byteHashValue, you'll see that it's c8059e2e....
Or, just add this code to your ComputeHash method:
Console.WriteLine(BitConverter.ToString(byteHashValue));
I would suggest rewriting your code to be:
public static string Encript(string strData)
{
string hashValue = HashData(strData);
return hashValue;
}
public static string HashData(string textToBeEncripted)
{
//Convert the string to a byte array
Byte[] byteDataToHash = System.Text.Encoding.Unicode.GetBytes(textToBeEncripted);
//Compute the MD5 hash algorithm
Byte[] byteHashValue = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(byteDataToHash);
return BitConverter.ToString(byteHashValue).Replace("-", "");
}
Oh, and a side note: the word is "Encrypt," not "Encript."
The problem in your case is not the encoding, but your conversion to string on the C# side. As long as you use the same encoding everywhere, it should work as expected. But note, that most of the online hashers use ASCII encoding, whereas you use System.Text.Encoding.Unicode which is UTF-16, thus the results will differ from the online encoders.
The code below will give the same result as your PHP snippet (ie c8059e2ec7419f590e79d7f1b774bfe6)
public static void Main(string[] args)
{
string a = "test";
string en = HashData(a);
Console.WriteLine(en);
}
public static string HashData(string textToBeEncripted)
{
Byte[] byteDataToHash = System.Text.Encoding.Unicode.GetBytes(textToBeEncripted);
Byte[] byteHashValue = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(byteDataToHash);
System.Text.StringBuilder s = new System.Text.StringBuilder();
foreach (var b in byteHashValue)
s.Append(b.ToString("x2"));
return s.ToString();
}
If you use System.Text.Encoding.ASCII instead, you will get 098f6bcd4621d373cade4e832627b4f6 as suggested in other answers. But then you'll have to use ASCII encoding in your PHP code as well.
This is because with UTF16 every character is represented by two bytes, and not only by one. Thus the byteDataToHash will have twice the size ([116, 0, 101, 0, 115, 0, 116, 0] vs [116, 101, 115, 116] in your case). And a different bytevector of course leads to a different hashvalue. But as said above, as long as all included components use the same encoding, it does not really matter which one you use.
I have a game made with Unity which is deployed in the WP store and I am trying to do the same for BB... however, after checking everything I have realized that I canĀ“t post the score I have made, into the DB I host online...
I think it is because of the MD5 function but I am not sure which are the APIs, BB uses...
Can anyone help me out a little, here, please?
This is the MD5 function I have (written in C#)
using UnityEngine;
using System.Collections;
using System.Text;
using System;
#if UNITY_WP8
using System.Security.Cryptography;
using UnityEngine.Windows;
using UnityEngine.WindowsPhone;
#else
using System.Security.Cryptography;
#endif
public static class Md5Functions
{
#if UNITY_WP8
static string md5val;
// Use this for initialization
static void Start () {
md5val = Md5Sum("Hello World!");
}
static void OnGUI()
{
GUILayout.Label(md5val);
}
public static string Md5Sum(string strToEncrypt)
{
System.Text.UTF8Encoding ue = new System.Text.UTF8Encoding();
byte[] bytes = ue.GetBytes(strToEncrypt);
byte[] hashBytes = Crypto.ComputeMD5Hash(bytes);
string hashString = "";
for (int i = 0; i < hashBytes.Length; i++)
{
hashString += System.Convert.ToString(hashBytes[i], 16).PadLeft(2, '0');
}
return hashString.PadLeft(32, '0');
}
#else
public static string Md5Sum(string strToEncrypt)
{
System.Text.UTF8Encoding ue = new System.Text.UTF8Encoding();
byte[] bytes = ue.GetBytes(strToEncrypt);
// encrypt bytes
System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] hashBytes = md5.ComputeHash(bytes);
// Convert the encrypted bytes back to a string (base 16)
string hashString = "";
for (int i = 0; i < hashBytes.Length; i++)
{
hashString += System.Convert.ToString(hashBytes[i], 16).PadLeft(2, '0');
}
return hashString.PadLeft(32, '0');
}
#endif
}
Thanks!
I want to hash given byte[] array with using SHA1 Algorithm with the use of SHA1Managed.
The byte[] hash will come from unit test.
Expected hash is 0d71ee4472658cd5874c5578410a9d8611fc9aef (case sensitive).
How can I achieve this?
public string Hash(byte [] temp)
{
using (SHA1Managed sha1 = new SHA1Managed())
{
}
}
For those who want a "standard" text formatting of the hash, you can use something like the following:
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)
{
// can be "x2" if you want lowercase
sb.Append(b.ToString("X2"));
}
return sb.ToString();
}
}
This will produce a hash like 0C2E99D0949684278C30B9369B82638E1CEAD415.
Or for a code golfed version:
static string Hash(string input)
{
var hash = new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(input));
return string.Concat(hash.Select(b => b.ToString("x2")));
}
For .Net 5 and above, the built-in Convert.ToHexString gives a nice solution with no compromises:
static string Hash(string input)
{
using var sha1 = SHA1.Create();
return Convert.ToHexString(sha1.ComputeHash(Encoding.UTF8.GetBytes(input)));
}
public string Hash(byte [] temp)
{
using (SHA1Managed sha1 = new SHA1Managed())
{
var hash = sha1.ComputeHash(temp);
return Convert.ToBase64String(hash);
}
}
EDIT:
You could also specify the encoding when converting the byte array to string as follows:
return System.Text.Encoding.UTF8.GetString(hash);
or
return System.Text.Encoding.Unicode.GetString(hash);
This is what I went with. For those of you who want to optimize, check out https://stackoverflow.com/a/624379/991863.
public static string Hash(string stringToHash)
{
using (var sha1 = new SHA1Managed())
{
return BitConverter.ToString(sha1.ComputeHash(Encoding.UTF8.GetBytes(stringToHash)));
}
}
You can "compute the value for the specified byte array" using ComputeHash:
var hash = sha1.ComputeHash(temp);
If you want to analyse the result in string representation, then you will need to format the bytes using the {0:X2} format specifier.
Fastest way is this :
public static string GetHash(string input)
{
return string.Join("", (new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(input))).Select(x => x.ToString("X2")).ToArray());
}
For Small character output use x2 in replace of of X2
I'll throw my hat in here:
(as part of a static class, as this snippet is two extensions)
//hex encoding of the hash, in uppercase.
public static string Sha1Hash (this string str)
{
byte[] data = UTF8Encoding.UTF8.GetBytes (str);
data = data.Sha1Hash ();
return BitConverter.ToString (data).Replace ("-", "");
}
// Do the actual hashing
public static byte[] Sha1Hash (this byte[] data)
{
using (SHA1Managed sha1 = new SHA1Managed ()) {
return sha1.ComputeHash (data);
}
I am trying to make use of a REST API using C#. The API creator has provided sample libraries in PHP, Ruby and Java. I am getting hung up on one part of it where I need to generate an HMAC.
Here's how it is done in the sample libraries they have provided.
PHP
hash_hmac('sha1', $signatureString, $secretKey, false);
Ruby
digest = OpenSSL::Digest::Digest.new('sha1')
return OpenSSL::HMAC.hexdigest(digest, secretKey, signatureString)
Java
SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes(), HMAC_SHA1_ALGORITHM);
Mac mac = null;
mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
mac.init(signingKey);
byte[] bytes = mac.doFinal(signatureString.getBytes());
String form = "";
for (int i = 0; i < bytes.length; i++)
{
String str = Integer.toHexString(((int)bytes[i]) & 0xff);
if (str.length() == 1)
{
str = "0" + str;
}
form = form + str;
}
return form;
Here's my attempt in C#. It is not working. UPDATE: The C# example below works just fine. I found out that the real problem was due to some cross-platform differences in newline characters in my signatureString.
var enc = Encoding.ASCII;
HMACSHA1 hmac = new HMACSHA1(enc.GetBytes(secretKey));
hmac.Initialize();
byte[] buffer = enc.GetBytes(signatureString);
return BitConverter.ToString(hmac.ComputeHash(buffer)).Replace("-", "").ToLower();
an extension to Vimvq1987's answer:
return hashValue.ToString(); doesn't produce the output you want/need. You have to convert the bytes in the array hashValue to their hex-string representation.
Can be as simple as return BitConverter.toString(hashValue); (prints upper-case letters A-F) or if you like it a bit more complex:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
public static string Encode(string input, byte[] key)
{
HMACSHA1 myhmacsha1 = new HMACSHA1(key);
byte[] byteArray = Encoding.ASCII.GetBytes(input);
MemoryStream stream = new MemoryStream(byteArray);
return myhmacsha1.ComputeHash(stream).Aggregate("", (s, e) => s + String.Format("{0:x2}",e), s => s );
}
static void Main(string[] args)
{
byte[] key = Encoding.ASCII.GetBytes("abcdefghijklmnopqrstuvwxyz");
string input = "";
foreach (string s in new string[] { "Marry", " had", " a", " little", " lamb" })
{
input += s;
System.Console.WriteLine( Encode(input, key) );
}
return;
}
}
}
which prints
3545e064fb59bc4bfc02b6e1c3d4925c898aa504
3249f4c8468d4d67f465937da05b809eaff22fdb
87baaadf5d096677f944015e53d283834eb1e943
6325376820c29a09e3ab30db000033aa71d6927d
54579b0146e2476595381d837ee38863be358213
and I get the exact same result for
<?php
$secretKey = 'abcdefghijklmnopqrstuvwxyz';
$signatureString = '';
foreach( array('Marry',' had',' a',' little',' lamb') as $s ) {
$signatureString .= $s;
echo hash_hmac('sha1', $signatureString, $secretKey, false), "\n";
}
edit: Dmitriy Nemykin suggested the following edit
public static string Encode(string input, byte[] key)
{
byte[] byteArray = Encoding.ASCII.GetBytes(input);
using(var myhmacsha1 = new HMACSHA1(key))
{
var hashArray = myhmacsha1.ComputeHash(byteArray);
return hashArray.Aggregate("", (s, e) => s + String.Format("{0:x2}",e), s => s );
}
}
which was rejected. But as James already pointed out in a comment to this answer at the very least the using statement is a good point.
This site has some pretty good examples across languages: http://jokecamp.wordpress.com/2012/10/21/examples-of-creating-base64-hashes-using-hmac-sha256-in-different-languages/
The c# implementation at the time of writing is:
private string CreateToken(string message, string secret)
{
secret = secret ?? "";
var encoding = new System.Text.ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(secret);
byte[] messageBytes = encoding.GetBytes(message);
using (var hmacsha256 = new HMACSHA256(keyByte))
{
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
return Convert.ToBase64String(hashmessage);
}
}
Try this:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha1.aspx
quick and dirty code:
public string Encode(string input, byte [] key)
{
HMACSHA1 myhmacsha1 = new HMACSHA1(key);
byte[] byteArray = Encoding.ASCII.GetBytes( input );
MemoryStream stream = new MemoryStream( byteArray );
byte[] hashValue = myhmacsha1.ComputeHash(stream);
return hashValue.ToString();
}