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!
Related
I am developing an app in C# .NET. The app will not connect to any database and during the installation it will create files and settings for the application and user. I want to store user data in a local file such as text file or flat file or JSON file.
In simple words I want to prevent user opening the file but if somehow user find a way to open it then at least he should not understand what information is stored. Is there any good method to encrypt file and data in it?
Just like how Google chrome stores data:
1 ŒA û œA àû ¯A ü ÂA °ü ÒA ý åA Pý õA À% B & B p& (B °m <B n OB ðn bB Po uB °o ˆB q ›B Àq ®B r ÁB €r ÔB s çB pt úB °u
C #v C v 3C x FC Àx YC z lC P| C °| ’C ð} ¥C P~ ¸C 0 ËC ÞC € ñC € D D ‚ *D °ƒ =D „ ND „
You can try encrypting the file and decrypt it when you need to access it.
Encryption
Decryption
Example of encryption and decryption from MS Docs:
using System.IO;
using System.Security.AccessControl;
namespace FileSystemExample
{
class FileExample
{
public static void Main()
{
try
{
string FileName = "test.xml";
Console.WriteLine("Encrypt " + FileName);
// Encrypt the file.
AddEncryption(FileName);
Console.WriteLine("Decrypt " + FileName);
// Decrypt the file.
RemoveEncryption(FileName);
Console.WriteLine("Done");
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.ReadLine();
}
// Encrypt a file.
public static void AddEncryption(string FileName)
{
File.Encrypt(FileName);
}
// Decrypt a file.
public static void RemoveEncryption(string FileName)
{
File.Decrypt(FileName);
}
}
}
I wrote a very simple text encryptor that you can use. Simply encrypt the text before storing it and decrypt it as you need it.
This will not stop someone who is willing to spend a little bit of time with a debugger, but just like locking your door it will keep honest people honest.
I also included some unit tests, feel free to remove them.
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
namespace Encryption;
public static class SimpleEncryptor
{
public static async Task<string> EncryptAsync(string cleartext, string password)
{
var hasher = SHA256.Create();
var key = hasher.ComputeHash(Encoding.UTF8.GetBytes(password));
using var aes = Aes.Create();
aes.Key = key;
aes.Padding = PaddingMode.PKCS7;
var iv = aes.IV;
var byteStream = new MemoryStream(10000);
byteStream.Write(iv, 0, iv.Length);
using var cryptoStream = new CryptoStream(
byteStream,
aes.CreateEncryptor(),
CryptoStreamMode.Write);
var encryptWriter = new StreamWriter(cryptoStream);
await encryptWriter.WriteAsync(cleartext);
encryptWriter.Close();
var bytes = byteStream.ToArray();
var base64 = Convert.ToBase64String(bytes);
return base64;
}
public static async Task<string> DecryptAsync(string ciphertext, string password)
{
var hasher = SHA256.Create();
var key = hasher.ComputeHash(Encoding.UTF8.GetBytes(password));
var encryptedArray = Convert.FromBase64String(ciphertext);
var byteStream = new MemoryStream(encryptedArray);
using var aes = Aes.Create();
aes.Key = key;
aes.Padding = PaddingMode.PKCS7;
var iv = new byte[aes.IV.Length];
var numBytesToRead = aes.IV.Length;
var numBytesRead = 0;
while (numBytesToRead > 0)
{
var n = byteStream.Read(iv, numBytesRead, numBytesToRead);
if (n == 0) break;
numBytesRead += n;
numBytesToRead -= n;
}
using var cryptoStream = new CryptoStream(
byteStream,
aes.CreateDecryptor(key, iv),
CryptoStreamMode.Read);
var decryptReader = new StreamReader(cryptoStream);
var decryptedMessage = await decryptReader.ReadToEndAsync();
return decryptedMessage;
}
}
public class EncryptorTests
{
[Test]
[TestCase("How do you turn this on?", "Swordfish", "GHzrU6z5hsgb6HSJtMZyirEs11sHY/X4l5zElwxHz9jpIGA+D9TAxv7SEU31/Jgb")]
[TestCase("Orange you glad I didn't say banana?", "hunter12", "qqNFxhwKYkkYzsN0vDzWhQguZ7f9xc+60duZXQATAzQslRhJsn6lc691+yVR0SWJYDJUD9ZbezpW/v4vYi6qeA==")]
[TestCase("Orange you glad I didn't say banana?", "hunter12", "TsjCbMOT4UKVi6L43Kkc0rMsl6IyeEfLBR3ruAsG+APUjb1zesVLGA/B0yF4FkFV/j1Rc5B55ClZYHV2zoubBA==")]
[TestCase("Your mother is rather fat.", "12345", "WD8e5E+PtQ5kMqkPSIZa18pDutbqn8OroSU5utHFTuikbgIWLA4IRAHihrfiXrV6")]
[TestCase("Yer' a wizard harry!", "Swordfish", "Z6tF/3iDTu72qTeVnKa8DZOsL5NFD9XfqJTWebANVrjQysm+8ps3Z9RuoJyenk30")]
public async Task TestDecryption(string text, string password, string ciphertext)
{
var decoded = await SimpleEncryptor.DecryptAsync(ciphertext, password);
Assert.AreEqual(text, decoded);
}
[Test]
[TestCase("How do you turn this on?", "Swordfish")]
[TestCase("Orange you glad I didn't say banana?", "hunter12")]
[TestCase("Your mother is rather fat.", "12345")]
[TestCase("Yer' a wizard harry!", "Swordfish")]
public async Task TestEncryptAndDecrypt(string text, string password)
{
var ciphertext = await SimpleEncryptor.EncryptAsync(text, password);
var decodedtext = await SimpleEncryptor.DecryptAsync(ciphertext, password);
Assert.AreEqual(text, decodedtext);
}
}
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();
}
}
}
I don't know if this is the correct place to ask, but I am having an issue hashing passwords for MySql Backend. I am running mosquitto 1.4.3 broker and I have the mosquitto-auth-plugin working on the same server. But I want to move the auth-plugin to a new server. So I created a admin program in C# to add users and access controls however I cant seem to the get the correct hash code for the password.
Has anyone implemented this or is there some resoucres available to create the correct hash?
I have tried this Hash It Right
private const int SaltByteLength = 12;
private const int DerivedKeyLength = 24;
public string CreatePasswordHash(string password)
{
var salt = GenerateRandomSalt();
var iterationCount = GetIterationCount();
var hashValue = GenerateHashValue(password, salt, iterationCount);
var iterationCountBtyeArr = BitConverter.GetBytes(iterationCount);
var valueToSave = new byte[SaltByteLength + DerivedKeyLength + iterationCountBtyeArr.Length];
Buffer.BlockCopy(salt, 0, valueToSave, 0, SaltByteLength);
Buffer.BlockCopy(hashValue, 0, valueToSave, SaltByteLength, DerivedKeyLength);
Buffer.BlockCopy(iterationCountBtyeArr, 0, valueToSave, salt.Length + hashValue.Length, iterationCountBtyeArr.Length);
return Convert.ToBase64String(valueToSave);
}
private int GetIterationCount()
{
return 901;
}
private static byte[] GenerateRandomSalt()
{
var csprng = new RNGCryptoServiceProvider();
var salt = new byte[SaltByteLength];
csprng.GetBytes(salt);
return salt;
}
private static byte[] GenerateHashValue(string password, byte[] salt, int iterationCount)
{
byte[] hashValue;
var valueToHash = string.IsNullOrEmpty(password) ? string.Empty : password;
using (var pbkdf2 = new Rfc2898DeriveBytes(valueToHash, salt, iterationCount))
{
hashValue = pbkdf2.GetBytes(DerivedKeyLength);
}
return hashValue;
}
will this make it easier for you?
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
class Class1
{
static void Main(string[] args)
{
byte[] HashValue;
string MessageString = "This is the original message!";
//Create a new instance of the UnicodeEncoding class to
//convert the string into an array of Unicode bytes.
UnicodeEncoding UE = new UnicodeEncoding();
//Convert the string into an array of bytes.
byte[] MessageBytes = UE.GetBytes(MessageString);
//Create a new instance of the SHA1Managed class to create
//the hash value.
SHA1Managed SHhash = new SHA1Managed();
//Create the hash value from the array of bytes.
HashValue = SHhash.ComputeHash(MessageBytes);
//Display the hash value to the console.
foreach(byte b in HashValue)
{
Console.Write("{0} ", b);
}
}
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();
}
I have a function that generates a MD5 hash in C# like this:
MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = md5.ComputeHash(data);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
sb.Append(result[i].ToString("X2"));
}
return sb.ToString();
In java my function looks like this:
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(bytes,0,bytes.length);
String hashcode = new BigInteger(1,m.digest()).toString(16);
return hashcode;
While the C# code generates: "02945C9171FBFEF0296D22B0607D522D" the java codes generates: "5a700e63fa29a8eae77ebe0443d59239".
Is there a way to generate the same md5 hash for the same bytearray?
On demand:
This is the testcode in java:
File file = new File(System.getProperty("user.dir") + "/HashCodeTest.flv");
byte[] bytes = null;
try {
bytes = FileUtils.getBytesFromFile(file);
} catch (IOException e) {
fail();
}
try {
generatedHashCode = HashCode.generate(bytes);
} catch (NoSuchAlgorithmException e) {
fail();
}
and this is my code in C#
var blob = GetBlobByHttpPostedFile(httpPostedFile);
var hashCode = Md5Factory.ConvertByteArray(blob);
private static byte[] GetBlobByHttpPostedFile(HttpPostedFile httpPostedFile)
{
var contentLength = httpPostedFile.ContentLength;
var result = new byte[contentLength];
var inputStream = httpPostedFile.InputStream;
inputStream.Read(result, 0, contentLength);
return result;
}
Cheers
That should be fine - although you could make the Java code simpler by just calling
byte[] digest = m.digest(bytes);
instead of calling update then digest.
Are you absolutely sure you've got the same data in both cases? Could you post sample programs showing this failing with the same hard-coded data?
EDIT: Here's the sort of test I was thinking of. These two programs give the same result:
C#:
using System;
using System.Security.Cryptography;
using System.Text;
class Test
{
static void Main()
{
byte[] bytes = { 0x35, 0x24, 0x76, 0x12 };
MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = md5.ComputeHash(bytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
sb.Append(result[i].ToString("x2"));
}
Console.WriteLine(sb);
}
}
Java:
import java.math.BigInteger;
import java.security.MessageDigest;
public class Test
{
public static void main(String[] args) throws Exception
{
byte[] bytes = { 0x35, 0x24, 0x76, 0x12 };
MessageDigest m = MessageDigest.getInstance("MD5");
byte[] digest = m.digest(bytes);
String hash = new BigInteger(1, digest).toString(16);
System.out.println(hash);
}
}
Hi I m using this code and it works
C# code :
public static string ConvertStringToMD5(string ClearText)
{
byte[] ByteData = Encoding.ASCII.GetBytes(ClearText);
//MD5 creating MD5 object.
MD5 oMd5 = MD5.Create();
//Hash değerini hesaplayalım.
byte[] HashData = oMd5.ComputeHash(ByteData);
//convert byte array to hex format
StringBuilder oSb = new StringBuilder();
for (int x = 0; x < HashData.Length; x++)
{
//hexadecimal string value
oSb.Append(HashData[x].ToString("x2"));
}
and Java code :
private String getMD5Digest(byte[] buffer) {
String resultHash = null;
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] result = new byte[md5.getDigestLength()];
md5.reset();
md5.update(buffer);
result = md5.digest();
StringBuffer buf = new StringBuffer(result.length * 2);
for (int i = 0; i < result.length; i++) {
int intVal = result[i] & 0xff;
if (intVal < 0x10) {
buf.append("0");
}
buf.append(Integer.toHexString(intVal));
}
resultHash = buf.toString();
} catch (NoSuchAlgorithmException e) {
}
return resultHash;
}
I came cross the similar issue that we were using Java MD5 Hash to determine whether a file has been processed. We found we cannot create same hash using .NET library. I tried all above suggestion, unfortunately it is not working for me.
The solution I found out later is: instead of create similar function in .NET, we call Java function directly in .NET. There is one great open source project called Ja.NET. Basically what i did is: create a Java class that create hash using the same code. compile it using Ja.NET javac. Then using bam compile the generated Java class file into DLL and use it in my .NET project.
I know this topic is old but I ran into the same issue just now and couldn't find an answer that worked for me. I was writing a patcher for a game and needed the md5 hashcode of files as a way to ensure that the files are up to date, but C# and Java gave me different strings although the files were identical.
Here's how I solved it:
C# Code:
public static string getMD5(string fullPath)
{
MD5 md5 = MD5.Create();
using (FileStream stream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
byte[] hash = md5.ComputeHash(stream);
StringBuilder sb = new StringBuilder();
for (int j = 0; j < hash.Length; j++)
{
sb.Append(hash[j].ToString("X2"));
}
return sb.ToString();
}
}
This creates a 32 character hex string. Apache Commons DigestUtils.md5Hex(InputStream) does the same, now the only different is that the C# example returns an uppercase string, so the solution is simply to convert the hash from the Java program to an uppercase string.
Java code:
public static String checkSumApacheCommons(String filePath)
{
String checksum = null;
try
{
checksum = DigestUtils.md5Hex(new FileInputStream(filePath));
}
catch (IOException ex)
{
ex.printStackTrace(System.out);
}
return checksum.toUpperCase();
}
The produced hashes look like F674865D8A44695A2443017CFA2B0C67.
Hope this helps someone.