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
Related
Is it possible to generate hash of a file using certificate information?
I have certificate details like this
"details": {
"certificate": "XIIHBTCCBO2gAwIBAgIQGuE3Q0ztnKRiYRN.....",
"public_key": "XIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQE...."
},
Using this information I need to create a digestvalue. Assuming the digest value is hash of a file created using the above certificate.
I am using below code to generate hash, but not able to figure out how to use certificate as well.
public static string SHA256CheckSum(string filePath)
{
using (SHA256 SHA256 = SHA256Managed.Create())
{
using (FileStream fileStream = File.OpenRead(filePath))
return Convert.ToBase64String(SHA256.ComputeHash(fileStream));
}
}
I want to convert the C code below into perl. Anyone know how to do this? Do you use hmac_sha1_hex($data, $key);? Do you use the digest:sha module? I want to sign some data with a key, but use perl instead of C.
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.Web;
namespace Amazon.Cba.Signature.Common
{
public class SignatureCalculator
{
public SignatureCalculator()
{
}
public String calculateRFC2104HMAC(String data, String key)
{
String result = null;
KeyedHashAlgorithm algorithm = new HMACSHA1();
Encoding encoding = new UTF8Encoding();
algorithm.Key = encoding.GetBytes(key);
result = Convert.ToBase64String(algorithm.ComputeHash(encoding.GetBytes(data.ToCharArray())));
return result;
}
}
}
I would do this like so:
use MIME::Base64 ();
use Digest::HMAC_SHA1 ();
my $result = MIME::Base64::encode_base64(
Digest::HMAC_SHA1::hmac_sha1( $data, $key ),
''
);
or if you want a url-safe base64 encoding:
my $result = MIME::Base64::encode_base64url(
Digest::HMAC_SHA1::hmac_sha1( $data, $key ),
);
though you can also use the separate Digest::HMAC and Digest::SHA modules together.
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.
I am trying to use a self signed certificate to sign a string and then verify that the string is signed correctly.
This is how I create my self signed certificate:
makecert -r -n "CN=AuthCert2" -ss my -a sha1 -pe
After this I export the certificate to a pfx file and try to run the following code:
using System;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
using System.Net;
using System.Net.Security;
[TestClass]
public class TestSign
{
[TestMethod]
public void TestSignAndVerify()
{
string toSignString = "This is my string to sign";
byte[] data = UnicodeEncoding.UTF8.GetBytes(toSignString);
SHA1Managed sha1 = new SHA1Managed();
byte[] hash = sha1.ComputeHash(data);
X509Certificate2 signCert = new X509Certificate2("authcert2.pfx", "authpass");
var csp = (RSACryptoServiceProvider)signCert.PrivateKey;
byte[] signedData = csp.SignData(hash, CryptoConfig.MapNameToOID("SHA1"));
RSACryptoServiceProvider csp2 = (RSACryptoServiceProvider)signCert.PublicKey.Key;
bool result = csp2.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), signedData);
}
}
Yet I am always getting result as false. I am sure I am missing something very basic here. Any idea what is going on or how I can debug the problem?
thanks,
There are two things wrong within the code. First of all, the SignData computation already includes calculating the hash (no need to do it yourself) and the second is that you are using VerifyHash instead of VerifyData.
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();
}