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.
Related
This is my first post and I am very sorry if I made errors with the format.
I am trying to write a program to encrypt all kinds of file via XOR in a secure way. I know that XOR isn't the most secure encryption method but I wanted to give it a try.
So please have a look on my methode and tell me if it is complete bullshit or not :)
The password is a String, chosen by the user.
In the beginning I only XORed the file with the password, leading to an easy decryption if parts of the password were guessed correctly.
Here is my procedure:
TmpFile = File XOR (hash of password combined with the pw.length.toString) //to make sure that the password elements are in the right order
TmpFile = TmpFile XOR (XOR byte composed by each byte of the password)//ensure that the password to decode has exactly the right chars.
TmpFile= TmpFile XOR initial_password
Could the encrypted text be decrypted with the self-XOR-shifting technique?
Thanks for your advice! :)
edit: here is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security;
using System.IO;
using System.Windows;
namespace EncodeEverything
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("FileEncrypter v01 \n \n");
//get password
Console.WriteLine("Enter your Password (encryption key)");
string password = getPassword();
Console.WriteLine("");
while (true)
{
Console.WriteLine("");
Console.WriteLine("-----------------------");
Console.WriteLine("");
//get file to encrypt
Console.WriteLine("File to encrypt/decrypt:");
Console.Write(" ");
string path = Console.ReadLine();
//-------------------------------
//load, encrypt & save file
//-------------------------------
try {
Byte[] tmpBArr = encrypt(File.ReadAllBytes(path), getCustomHash(password));
File.WriteAllBytes(path, encrypt(tmpBArr, password));
Console.WriteLine(" done.");
}
catch(System.Exception e)
{
Console.WriteLine("!! Error while processing. Path correct? !!");
}
}
}
private static string getCustomHash(string word)
{
string output = "";
output += word.Length.ToString();
output += word.GetHashCode();
return output;
}
//encrypt bzw decrypt Byte[]
public static Byte[] encrypt(byte[] s, string key)
{
List<Byte> output = new List<byte>();
Byte[] codeword = Encoding.UTF8.GetBytes(key);
Byte keybyte =(Byte)( codeword[0]^ codeword[0]);
foreach(Byte b in codeword)
{
keybyte = (Byte)(b ^ keybyte);
}
for (int i = 0; i < s.Length; i++)
{
output.Add((Byte)(s[i] ^ codeword[i % codeword.Length] ^ keybyte));
}
return output.ToArray();
}
public static string getPassword()
{
Console.Write(" ");
string pwd = "";
while (true)
{
ConsoleKeyInfo i = Console.ReadKey(true);
if (i.Key == ConsoleKey.Enter)
{
break;
}
else if (i.Key == ConsoleKey.Backspace)
{
if (pwd.Length > 0)
{
pwd= pwd.Remove(pwd.Length - 1);
Console.Write("\b \b");
}
}
else
{
pwd+=(i.KeyChar);
Console.Write("*");
}
}
return pwd;
}
}
}
string.GetHashCode doesn't have a well defined return value. So you might not even be able to decrypt the file after you restart the process.
Your key consists of a 32 bit value plus the length of the password. Brute-forced in seconds on a single computer.
Once the file is longer than the hashed key, the key starts repeating, you get a many-time-pad. So even if we ignored the brute-force attack, it'd still be easy to break. It's essentially a xor based vigenere variant.
Ignoring the xor-ed parity byte, which is the same for each byte in the message, the key-stream bytes are ASCII digits, so each key byte has at best 3.3 bits of entropy. Comparing this with the approximately 1.5 bits of entropy per letter in English text, shows you that it's quite weak, even without key-stream repetitions.
=> it's buggy and insecure
You can ignore this answer if you're just trying to encrypt files as a learning exercise in cryptography, but if you're looking for a real-world solution to securing your file data, read on.
I'd really recommend that you use File encryption built into the .NET framework for this sort of thing if you're looking for a real-world solution to keeping your file data secure.
From Microsoft # https://msdn.microsoft.com/en-us/library/system.io.file.encrypt(v=vs.110).aspx
using System;
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);
}
}
}
It is hard to say for sure that this is what you need, because other things may need to be taken into consideration such as whether you need to pass the file between different clients/servers etc, as well as how much data you're encrypting in each file.
Again, if you're looking for real-world cryptography using C#, I can't stress enough that you should be looking to built-in .NET encryption rather than trying to roll your own- especially if you don't have any formal training in the subject matter. I recommend you pore through Microsoft documentation on .NET framework encryption if you're interested in securing data in production:
https://msdn.microsoft.com/en-us/library/0ss79b2x(v=vs.110).aspx
Here is a nice walkthrough for creating an example file encrypting windows form application:
https://msdn.microsoft.com/en-us/library/bb397867(v=vs.110).aspx
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
I'm trying to build a portable class library that generates OAuth urls for other classes/applications to use. This class library using OAuth has to be a portable class library so it can work with different versions of a DropBox API I'm building.
Part of this class needs to generate an SHA1 hash to generate the oauth_signature with.
I'm aware that portable class library doesn't support System.Security.Cryptography, so is there anyway that this class can generate an SHA1 hash without that class?
I think the easiest way is to use the PCLCrypto nuget package. Then you can do:
private static string CalculateSha1Hash(string input)
{
// step 1, calculate MD5 hash from input
var hasher = WinRTCrypto.HashAlgorithmProvider.OpenAlgorithm(HashAlgorithm.Sha1);
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
byte[] hash = hasher.HashData(inputBytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
Well I needed this too recently and I found much easier to take SHA1 implementation from HashLib : http://hashlib.codeplex.com/
Mono implementation have some far-going dependencies (localization of exceptions, etc.), while from HashLib you need only to copy few files without any changes in them:
Converters.cs
Hash.cs
HashBuffer.cs
HashCryptoNotBuildIn.cs
HashResult.cs
IHash.cs
SHA0.cs
SHA1.cs
55 KB of code total, so nothing too heavy.
I have used this BouncyCastle Nuget package: https://www.nuget.org/packages/BouncyCastle-PCL/ and it works just fine for me (cross platforms Windows Store App, .Net Framework 4.5, Silverlight 5, Windows Phone 8, Xamarin.Android, Xamarin.iOS)
Use HMACSHA1 to generate signature like this:
public string GenerateSignature(string key, string signatureBase)
{
var keyBytes = Encoding.UTF8.GetBytes(key);
HMACSHA1 hashAlgorithm = new HMACSHA1(keyBytes);
byte[] dataBuffer = Encoding.UTF8.GetBytes(signatureBase);
byte[] hashBytes = hashAlgorithm.ComputeHash(dataBuffer);
return Convert.ToBase64String(hashBytes);
}
Mono provides a managed implementation of SHA1 for it's own mscorlib.dll (but it's not located in Mono.Security.dll like #CodeInChaos suggested).
It's open source, very well tested and meant to behave exactly like Microsoft implementation (e.g. it derives from SHA1, HashAlgorith... implements ICryptoTransform...) so it should be an easy drop-in replacement.
The SHA-1 Wikipedia article contains pseudocode that you could use as a guideline for your own implementation. But, as always with cryptographic functions, I strongly advise to use a tried and tested implementation.
Assuming you want a SHA-256 implementation, you can find one in BouncyCastle, which is available in source code form. The relevant class there is called Org.BouncyCastle.Crypto.Digests.Sha256Digest (here's its source).
You might want to check out the new .NET Standard library:
https://learn.microsoft.com/en-us/dotnet/articles/standard/library
It is portable, and System.Security.Cryptography is included.
/// <summary>
/// Compute hash for string encoded as UTF8
/// </summary>
/// <param name="input">String to be hashed.</param>
/// <returns>40-character hex string.</returns>
public static string GetSha1(string input)
{
using (var sha1 = System.Security.Cryptography.SHA1.Create())
{
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
byte[] hash = sha1.ComputeHash(inputBytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
}
You might also get some help (for creating a PCL project with .NET Standard Library) here:
https://xamarinhelp.com/dot-net-standard-pcl-xamarin-forms/
Here is an example using BouncyCastle
public static string ComputeSha1(string data)
{
var sha1Digest = new Org.BouncyCastle.Crypto.Digests.Sha1Digest();
var hash = new byte[sha1Digest.GetDigestSize()];
var dataBytes = Encoding.UTF8.GetBytes(data);
foreach (var b in dataBytes)
{
sha1Digest.Update(b);
}
sha1Digest.DoFinal(hash, 0);
return string.Join("", hash.Select(b => b.ToString("x2")).ToArray());
}
I wanted sign OAuth also, and am looking at PCL Crypto - this test shows creation of a HmacSha1 hash, and compares the result to the standard .NET Framework way.
[Test]
public void CreateHash_VersusComputeHash_ReturnsEquivalent()
{
// USING TRADITIONAL .NET:
var key = new byte[32];
var contentBytes = Encoding.UTF8.GetBytes("some kind of content to hash");
new RNGCryptoServiceProvider().GetBytes(key);
var alg = new HMACSHA1(key); // Bouncy castle usage does not differ from this
var result = alg.ComputeHash(contentBytes);
// USING PCL CRYPTO:
var algorithm = WinRTCrypto.MacAlgorithmProvider.OpenAlgorithm(MacAlgorithm.HmacSha1);
byte[] mac;
using (var hasher = algorithm.CreateHash(key))
{
hasher.Append(contentBytes);
mac = hasher.GetValueAndReset();
}
// Assert results:
Assert.AreEqual(result.Length, mac.Length);
for (var i = 0; i < result.Length; i++)
{
Assert.AreEqual(result[i], mac[i]);
}
}
This worked for me when I had to achieve the same outcome. You can do this with SHA512 and others too.
using System.Security.Cryptography;
public static string HashSHA1(this string value)
{
using (var sha = SHA1.Create())
{
return Convert.ToBase64String(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes(value)));
}
}
Code cited from: https://xamarinhelp.com/cryptography-in-xamarin-forms/
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();
}
I need two methods one to encrypt and one to decrypt an xml file with a key= "hello world",the key hello world should be used to encrypt and decrypt the xml file.These methods should work on all machines!!! Any encryption methods will do. XML File contents below:
<root>
<lic>
<number>19834209</number>
<expiry>02/02/2002</expiry>
</lic>
</root>
Can some give me a sample?The issue is the msdn sample encyptions make a xml file encypted but when I decrypt on another machine it doesn't work.For example
I tried this sample:
How to: Encrypt XML Elements with Asymmetric Keys,
but here there is some kinda session and on another machine it says bad data phewf!
If you want the same key for encrypting and decrypting you should use a symmetric method (that's the definition, really). Here's the closest one to your sample (same source).
http://msdn.microsoft.com/en-us/library/sb7w85t6.aspx
The posted sample isn't working because they aren't using the same keys. Not only on different machines: running the program on the same machine twice should not work either (didn't work for me), because they use different random keys every time.
try adding this code after creating your key:
key = new RijndaelManaged();
string password = "Password1234"; //password here
byte[] saltBytes = Encoding.UTF8.GetBytes("Salt"); // salt here (another string)
var p = new Rfc2898DeriveBytes(password, saltBytes); //TODO: think about number of iterations (third parameter)
// sizes are devided by 8 because [ 1 byte = 8 bits ]
key.IV = p.GetBytes(key.BlockSize / 8);
key.Key = p.GetBytes(key.KeySize / 8);
Now the program is using the same key and initial vector, and Encrypt and Decrypt should work on all machines.
Also, consider renaming key to algorithm, otherwise this is very misleading. I'd say it's a bad, not-working-well example from MSDN.
NOTE: PasswordDeriveBytes.GetBytes() has been deprecated because of serious (security) issues within the PasswordDeriveBytes class. The code above has been rewritten to use the safer Rfc2898DeriveBytes class instead (PBKDF2 instead of PBKDF1). Code generated with the above using PasswordDeriveBytes may be compromised.
See also: Recommended # of iterations when using PKBDF2-SHA256?
First of all, if you want to use the same key for encrypting and decrypting, you should look at symmetric cryptography. Asymmetric cryptography is when the keys for encrypting and decrypting are different. Just so that you know - RSA is asymmetric, TripleDES and Rijndael are symmetric. There are others too, but .NET does not have default implementations for them.
I'd advise studying the System.Security.Cryptography namespace. And learning a bit about all that stuff. It has all you need to encrypt and decrypt files, as well as generate a password. In particular, you might be interested in these classes:
CryptoStream
PasswordDeriveBytes
RijndaelManaged
There are also examples for usage in MSDN for each of them. You can use these classes to encrypt any file, not just XML. If however you want to encrypt just a select few elements, you can take a look at System.Security.Cryptography.Xml namespace. I see you've already found one article about it. Keep following the links on that page and you will learn more about those classes.
Would be cooler if you used a private key to sign the <lic> element and added the result to the file (in a <hash> element perhaps). This would make it possibly for everyone to read the xml file in case your support needs to know the license number, or the date of expiry, but they can not change any values without the private key.
The public key needed to verify the signature would be common knowledge.
Clarification
Signing your code will only protect it against changes, it will not keep any information in it hidden. Your original question mentions encryption, but I am not sure that it is a requirement to hide the data, or just protect it from modification.
Example code: (Never publish PrivateKey.key. ServerMethods are only needed when signing the xml file, ClientMethods are only needed when verifying the xml file.)
using System;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
public static class Program {
public static void Main() {
if (!File.Exists("PublicKey.key")) {
// Assume first run, generate keys and sign document.
ServerMethods.GenerateKeyPair();
var input = new XmlDocument();
input.Load("input.xml");
Debug.Assert(input.DocumentElement != null);
var licNode = input.DocumentElement["lic"];
Debug.Assert(licNode != null);
var licNodeXml = licNode.OuterXml;
var signedNode = input.CreateElement("signature");
signedNode.InnerText = ServerMethods.CalculateSignature(licNodeXml);
input.DocumentElement.AppendChild(signedNode);
input.Save("output.xml");
}
if (ClientMethods.IsValidLicense("output.xml")) {
Console.WriteLine("VALID");
} else {
Console.WriteLine("INVALID");
}
}
public static class ServerMethods {
public static void GenerateKeyPair() {
var rsa = SharedInformation.CryptoProvider;
using (var keyWriter = File.CreateText("PublicKey.key"))
keyWriter.Write(rsa.ToXmlString(false));
using (var keyWriter = File.CreateText("PrivateKey.key"))
keyWriter.Write(rsa.ToXmlString(true));
}
public static string CalculateSignature(string data) {
var rsa = SharedInformation.CryptoProvider;
rsa.FromXmlString(File.ReadAllText("PrivateKey.key"));
var dataBytes = Encoding.UTF8.GetBytes(data);
var signatureBytes = rsa.SignData(dataBytes, SharedInformation.HashAlgorithm);
return Convert.ToBase64String(signatureBytes);
}
}
public static class ClientMethods {
public static bool IsValid(string data, string signature) {
var rsa = SharedInformation.CryptoProvider;
rsa.FromXmlString(File.ReadAllText("PublicKey.key"));
var dataBytes = Encoding.UTF8.GetBytes(data);
var signatureBytes = Convert.FromBase64String(signature);
return rsa.VerifyData(dataBytes, SharedInformation.HashAlgorithm, signatureBytes);
}
public static bool IsValidLicense(string filename) {
var doc = new XmlDocument();
doc.Load(filename);
var licNode = doc.SelectSingleNode("/root/lic") as XmlElement;
var signatureNode = doc.SelectSingleNode("/root/signature") as XmlElement;
if (licNode == null || signatureNode == null) return false;
return IsValid(licNode.OuterXml, signatureNode.InnerText);
}
}
public static class SharedInformation {
public static int KeySize {
get { return 1024; }
}
public static string HashAlgorithm {
get { return "SHA512"; }
}
public static RSACryptoServiceProvider CryptoProvider {
get { return new RSACryptoServiceProvider(KeySize, new CspParameters()); }
}
}
}
this is how you digitally sign and verify XML documents Sign XML Documents