I am working with some old code and I don't understand what has been done when creating a signed hash. The authors used this implementation:
AsymmetricSignatureFormatter.CreateSignature(HashAlgorithm)
All the examples I can find, and all the Microsoft documentation, use the other implementation:
AsymmetricSignatureFormatter.CreateSignature(byte[]HashedDataValue)
I understand that the second approach is signing a hash of some user data. At the receiver, we can re-hash the received plain text and compare it with this sent signed version to confirm it hasn't been changed.
But what is the first approach trying to do? No signed data seems to be sent, only a signed version of 'the agorithm', but what actually gets signed? Does it sign the Hash.hash byte array? But if so, there is no plain text byte array at the receiver to re-hash and check the sent hash against.
I suspect I have some fundamental misunderstanding of the purpose of this implementation.
It turns out that to use this form:
AsymmetricSignatureFormatter.CreateSignature(HashAlgorithm)
you need to have done some pre-work with the HashAlgorithm object. The HashAlgorithm object internally stores the hash of the last thing it 'hashed'.
Hence, if alg is the HashAlgorithm and userData is a byte array then
alg.ComputeHash(userData)
will store the hash within the alg object. Now we can sign the hash of userData using this form of the method:
AsymmetricSignatureFormatter.CreateSignature(HashAlgorithm)
Related
I'd like to know if there is a standard code to generate a SHA256 hash using a key. I've come across several types of code, however, they don't generate the same output.
Code found at JokeCamp
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);
}
}
Here's another one that I found
private static string ComputeHash(string apiKey, string message)
{
var key = Encoding.UTF8.GetBytes(apiKey);
string hashString;
using (var hmac = new HMACSHA256(key))
{
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
hashString = Convert.ToBase64String(hash);
}
return hashString;
}
The code generated by both of these are different to what is generated by http://www.freeformatter.com/hmac-generator.html#ad-output
I'll be using the SHA256 for one of our external API's where consumers would hash the data and send it to us. So we just want to make sure we use a standard approach so that they send us the correct hash. Also, I would like to know if there are any well-known nugets for this. I've also tried to find a solution with Bouncy Castle, however, I couldn't find one that uses a key to hash.
The difference is because of the character encodings (ASCII vs UTF-8 in your examples). Note that the hashing algorithm takes an array of bytes, and you do the conversion from a string to that byte-array beforehand.
Your question "whats the standard code" probably hasnt an answer, id say that if you expect the input to contain content from just the ASCII character-space, go for that, if not go for UTF-8. Either way - communicate it to your users
If you want to look at it from a usability perspective and make it the optimal for your users - go for both. Hash the content both ways and check agains the users incoming hash, but it all depends on your evaluation on clock-cycles vs security vs usability (you can have two)
They are almost equivalent.
The difference is how the encoding for the string is established.
In the first portion of code it assumes ASCII, whereas in the second portion it assumes UTF-8. It is possible that the string used another encoding which is none of those.
But regardless of that, the idea is to understand what is the goal of this operation. The truly relevant things in this context are:
Given equal input, output should be the same
There should be no way to retrieve the plaintext only by knowing the output (within a reasonable amount of time)
After hashing, you no longer require the original input in plaintext.
A secure cryptographic hashing function (meaning not older functions like MD5) achieves that.
Then, if your data store where hashes are stored is compromised, the attacker would only have a hash which cannot be used to retrieved the original plaintext. This is why hashing is used rather than encryption, encryption is a reversible operation (through decryption).
Then, within the system, if you've made the decision to use one encoding, you need to keep that decision consistent across all components in your system so they can interoperate.
This question already has answers here:
Hashing a SecureString in .NET
(4 answers)
Closed 7 years ago.
I believe I'm misunderstanding a fundamental part of SecureString. I understand that string's are immutable and there a password or sensitive data is found as clear text on the heap.
What I'm struggling to understand is, how do I use SecureString in a client application which needs to verify the hashed password in a database?
Here's my context:
I'm using a WPF client application.
I have a local SQL database (on the client's machine)
The passwords are hashed and stored in the database.
The user tries logging into to my WPF application
The PasswordBox control stores the password in a SecureString via the SecurePassword property.
Now what? How do I hash a SecureString WITHOUT casting it back into string first?
All the advise I've received so far is to write extension methods converting SecureString to String, hash it and then send it to db to verify. But this defeats the whole exercise!
Must I just accept that SecureString is useless in my mentioned context and use plain string?
SecureString is represented as a byte[] you could encode the bytes e.g. with bitconverter and save the result.
Furthermore SecureString is a encryption not a hash as it can be decrypted. (see below)
SecureString mainly meant to store sensitive data in memory.
If you have a service / website, this is not as important as the values which are stored in the database. These should never be plaintext, and imo not be decryptable by your or any administrator
Also i'm not sure wether another server could decrypt the strings, so you may have a problem when you change the server or have somekind of cluster scenario.
Especially for passwords would prefer using hash algorithms (e.g. SHA256) .
These can't be uncrypted (like the sum of the digits).
In the use case of a login funtionality you would encrypt the userinput and compare the hashs the user and and the one thats in the database. (details se below)
I would also suggest to add a dynamic criteria like the userid to the hashinput so that 2 user with same password would have different hashes.
With this strategy you don't have a risc with userpasswords and therefore if data gets leaked it wouldn't be a problem at this point.
Here an short overview of using hash algorithms
So ( if the securestring is given) first decrypt the SecureString
String SecureStringToString(SecureString value){
IntPtr valuePtr = IntPtr.Zero;
try{
valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value);
return Marshal.PtrToStringUni(valuePtr);
}
finally{
Marshal.ZeroFreeGlobalAllocUnicode(valuePtr);
}
}
Than hash it for example with SHA256. From this post
using (SHA256 hash = SHA256Managed.Create()) {
Encoding enc = Encoding.UTF8;
//the user id is the salt.
//So 2 users with same password have different hashes.
//For example if someone knows his own hash he can't see who has same password
string input = userInput+userId;
Byte[] result = hash.ComputeHash(enc.GetBytes(input));
foreach (Byte b in result)
Sb.Append(b.ToString("x2")); //You could also use other encodingslike BASE64
}
Store this hashsum. Depending on your encoding it may looke like this:
ac5b208b4d35ec79fa7c14b7a31f9c80392cdab2bc58bc5b79bcfe64b044d899
in your database.
If the user signs on then create the hash from his input and compare it with the hash in the database. if they are equal then the password is correct.
Therefore you never need to have the plaintext user password anywhere stored.
If the client makes the hash then it should absolut should no where exist as a plaintext (except the textbox if it doesnt support the securestring)
PS: this is only one option. But the main thing is to never store plaintextpasswords anywhere. For best never know them and have no change to get them decrypted.
Another strategy would be to use asymmetric encryptions like RSA but this can become more complex. If you need help with that i would recommend a dedicated post on this.
Depending on your requirements and envionment most of the time hashsums should be an acceptable solution. (But thats not an legal advice as i'm not a lawyer)
I really don't understand what the _verify function does in this class :
http://code.google.com/p/as3crypto/source/browse/trunk/as3crypto/src/com/hurlant/crypto/rsa/RSAKey.as
And especially what does it put into the 'dst' variable. I actually have a "verify key" wich use this method on an encrypted data, and I get the public key in the dst variable...
Here is a small diagram, so that you understand better: http://i.imgur.com/R8DqT.png
Thanks
Ps : I have to do the same in .net,so if you know something equivalent, let me know it
The function _verify (included for reference below)
public function verify(src:ByteArray, dst:ByteArray,
length:uint, pad:Function = null):void {
_decrypt(doPublic, src, dst, length, pad, 0x01);
}
Looking at the link you supplied, the function is used to verify RSA signed data - the result is copied to the dst ByteArray.
Breakdown:
doPublic = function parameter, a wrapper around BigInteger.modPowInt()
src = byte array with signed data
dst = byte array which will hold the result of with verification result
length = length of the data in src byte array
pad = function parameter, a wrapper for pkcs1pad (_encrypt) and pkcs1unpad (_decrypt)
0x01 = padType - an integer value specifying if a fixed value (0xff) is used in padding (0x01) or a pseudo-random one (0x02) - (only actually used in pkcs1pad which is called from _encrypt)
In the RSA scheme, signed data is verified by decrypting the signature using the public key.
Update: Unless you have very specific needs which are not covered, is see no reason why you want to port the ActionScript-3 you posted. Use the c# RSACryptoServiceProvider which is included in the framework. Take special note of the section Interoperation with the Microsoft Cryptographic API (CAPI) in the MSDN description.
Addressing your comments about needing the content of the dst byte array in a similar manner to the AS3Crypto implementation you could just create a wrapper to decrypt the signed data against the public key. Have a look at RSACryptoServiceProvider.ImportParameters() function which you use to import the public key information. Since you haven't provided details as to how the public key is retrieved I can't be more specific. This implementation example should help with parsing key files to create appropriate RSAParameters to feed to the ImportParameters method.
I am trying to connect my system to a banks payment system. The problem is, their documentation was mostly not correct, if it wasn't a complete disaster.
In the documentation of 3D secure system, the bank asks me to fill out a html form and submit it to their system. The form should include some data AND a SHA1 hash of the data with the data. I tried many times but the bank's system returned "Hash not correct" error all the time.
After some inspection on their example C# code, I found a function they used to get hash results. The problem is function was doing some other stuff to the data rather than just hashing them. And bigger problem is I cannot find out what this piece of code is doing to the string that hashed.
public static string CreateHash(string notHashedStr)
{
SHA1 sha1 = new SHA1CryptoServiceProvider();
byte[] notHashedBytes = System.Text.Encoding.ASCII.GetBytes(notHashedStr);
byte[] hashedByte = sha1.ComputeHash(notHashedBytes);
string hashedStr = System.Convert.ToBase64String(hashedByte);
return hashedStr;
}
I have nearly no experience on .Net framework and also I am on a mac, so I cannot test the code easily, and MSDN is definitely not for me(I am a Ruby developer most of the time, and I know enough C). If anyone can explain what these functions do to the string to be hashed, i'll be very glad.
It's very simple.
Get the ASCII encoded bytes from notHashedStr.
Create a SHA1 hash from that bytes
Convert that hash in a Base64 encoded string.
return that Base64-SHA1-ASCII-String.
I never did any ruby, but it must look a bit like this.
require 'digest/sha1'
returnValue = Digest::SHA1.base64digest 'notHashedStr'
I need to generate a checksum over a dictionary. Keys and Values.
Is there any simple way to accomplish this in an iterative way.
foreach(var item in dic.Keys)
checksum += checksum(dic[item]) + checksum(item);
In this case, keys and values could be converted to strings, concatinated and then a single checksum applied over these but is there a better way?
Ideally MD5 but other options could work. Using this to validate data that is passed over a couple of storage methods. The checksum is then encrypted along with some other information (using AES) so I am not horribly worried about an ideal, unbreakable checksum.
Generating a signature is pretty much the same process all over: create a MD5 hash object, then you digest all the bytes of interest, then you extract the hash value. The important thing is that you and the verifier agree on the bytes to hash and on the order they are hashed.
In C# you can achieve this by calling HashAlgorithm.TransformBlock repeatedly, and then finally calling HashAlgorithm.TransformFinalBlock. This is automated by using a CryptoStream with a HashTransform (MD5 implements ICryptoTransform) and then simply writing your dictionary into the crypto stream.
As aside note, countless protocols and crypto schemes that digest a hash and encrypt it were humiliated in the wild. I would suggest taking the beaten path and use well established industry standards::
Use a HMAC, see HMACMD5
Use an RSA signature (ie. private key encryption of an MD5 hash), and save your self from all key provisioning and master secret exchange problems, see RSACryptoServiceProvider.SignHash
Answered my own question I think....
GetHashCode() on each item. Add them in an unchecked {} environment. Too simple.
You should not be writing any new code relying on MD5. It's deprecated, and for some extremely solid reasons. You should look at SHA-256, or at the very least SHA-1, instead
And you should take Remus' advice. Cryptography + hashes = digital signatures. Pull something down off a shelf (just not XML-Security, please!), learn it, use it, and get on to other interesting parts of your project.