Asp.net C# Encryption/Decryption on Client and server Side - c#

Sir,
I have the jquery solution to encryption on the client side but it create "MD5" only.
I want Salted Md5 Encryption on the Clientside
and Decrypt it at the Server Side in Asp.net 4.0 and C#
My Code for encryption are as follows:
<script type="text/javascript">
function chn() {
var a = document.getElementById('txt1');
var b = document.getElementById('txt2');
var c = a.value; var d = $.md5(c);
b.value = (d);
}
</script>
I want that encryption must be change on every attempt..
Example : first time encryption of abc is xyz
and again if I will try with that name "Abc" then it should create another Encryption
and check on server Side.
Please Help me out

MD5 is a hash, not an encryption mechanism. Hashes are by their very nature lossy, and multiple inputs can (and by virtue of the pigeonhole principle absolutely will) produce the same outputs.
Running MD5 works like counting the number of vowels in a word. If I tell you that a word has 4 vowels in it, and ask you to tell me what the original word was, you simply don't have enough information to give me the the correct answer. You may be able to find some word that has 4 vowels in it, but you won't know whether the word you found was my word. Maybe it is, maybe it isn't. It's mathematically impossible for you to tell.
MD5 works the same way. You're throwing away tons of information, possible gigabytes or terabytes of information, and producing instead a single 16-byte summary.
It is, by intention, an inherently one-way process.

MD5 cant be decrypted. It is a one way hash. Beside I find that anything that could be decrypted on the other end is insecure, in the case it is intercepted. Always design and code to ensure that you can validate a salt and not decrypt it :)

Related

Translate C# code to Ruby Code

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'

Encoding two values in a short URL token

I am working on a short URL app, where the token must identify 2 values: the link ID and the user ID. Ideally this token should be short.
For example, considering the URL http://sho.rt/15qq6, the token "15qq6" must identify the link and user ID.
I guess one option is to insert both values in a table and use the auto-generated ID as a token, but I would rather not. I would prefer a solution involving encryption.
How could I use the .NET encryption classes for such purpose, if possible? Many thanks for your help.
I'm not clear on how short you want your code. I posted some code online to encrypt any number of query arguments.
The result could be shortened by base64-encoding the result. That might still not be short enough for you though. (Note that I didn't base64-encode it because I had some concerns about base64 encoding is case-sensitive.)
Another approach would be to come up with a code that consists of an ID into your database and some sort of checksum. If the user tries modifying the ID, you could detect this. However, this approach may not be that secure since it might not be that hard to figure out how to create your own checksums.
Short answer is "You can't", at least, not easily.
Encryption typically doesn't change the length of the data being encrypted. So if you take the URL and UserId that you want to encode and encrypt them you'll end up with a token that's the same total length.
You could try compressing the data before encryption, but there's not a lot of redundancy in a single URL, and this won't buy you much.
You culd hash the data to give you a shorter result, but there's no way to reverse this process to get your URL and userId back.
If it's a short token you need then the only real option I can think of is a lookup table on the server, using the token as the key.
I don't think you understand exactly how Encryption works.
Encryption is just a technique for making it difficult to decode the response, without knowing the original encryption key.
The encrypted data is at least as long as the original data, if not larger.
There is no viable way of encoding a URL into a smaller amount of data, that's still valid in a URL.
Use a database for this, that's what they're for.
Edit: D'oh, Andrew beat me to it with a better response after editing.
You could use something like the RNGCryptoServiceProvider to generate a unique set of characters. Use a few constants strings holding a range of characters like "a" to "z", "A" to "Z", and "1" to "9". Save the randomly mixed case alphanumeric string with the original URL and UserID.
Generate random token and save link and user id in db for this token. It is security enough.
If you don't need encryption, than simple combination of Convert.ToBase64String and BitConverter.GetBytes will give you reasonable string. Note that Base64 uses some non-url cahnracters, so consider replacing them in result WikiPedia Base64, or using Base32 encoding.
int first =1234;
int second =789;
var encoded = Convert.ToBase64String(
BitConverter.GetBytes (((ulong)first<<32)+(ulong)second));

Encrypting Windows Phone Resources at the Bit Level... am I doing this right?

I have a question concerning encryption, more specifically encryption that requires no internet connection (opposed to private / public key or OAuth methods).
The problem arose when I discovered that the WP7 app store is not secure. I won't post a link, but a basic search will yield a desktop application that allows you to download any free WP7 in the marketplace. Then it's a matter of renaming .xap to .zip, and using reflector to look at the code.
I believe that Dotfuscator will solve my problem, but as a learning experience I decided to come up with my own solution.
I decided to have a program that in prebuild gathers the files I want to encrypt, puts them in one file, encrypts that file, and adds it to the project for compilation. Code in the phone app only needs to decrypt the data.
The data I'm encrypting / decrypting is several API Keys (for ~10 web services), meant to be readable as plain text when decrypted.
This is the encryption algorithm (roughly, and with a few alterations) that I came up with:
public static byte[] SuffleData(byte[] data)
{
// Create a bit array to deal with the data on the bit level
BitArray bits = new BitArray(data);
// Generate a random GUID, and store it in a bit array as well
Guid guid = Guid.NewGuid();
BitArray guidBits = new BitArray(guid.ToByteArray());
int guidBitsIndex = 0;
// Iterate over all the data bit by bit
for (int i = 0; i < bits.Count / 2; i++)
{
// if the current GUID bit is true (1), then swap
// the current bit with it's mirror
if (guidBits[guidBitsIndex])
{
bool temp = bits[i];
bits[i] = bits[bits.Length - i];
bits[bits.Length - i] = temp;
}
// Because the data being shuffled is expected to
// contain more bits than the GUID, this index
// needs to be reset
if (guidBitsIndex == guidBits.Count)
guidBitsIndex = 0;
else
guidBitsIndex++;
}
// HideGuidInData hides the bits for the GUID in a hard
// coded location inside the data being encrypted.
HideGuidInData(ref bits, guidBits);
// Convert the shuffled data bits (now containing the
// GUID needed to decrypt the bits) into a byte array
byte[] shuffled = new byte[bits.Length / 8];
bits.CopyTo(shuffled, 0);
// return the data, now shuffled. (this array should
// be the length of the original data, plus 16 bytes,
// since 16 bytes are needed to store the GUID).
return shuffled;
}
I may be shooting myself in the foot posting this, but if it's not known that the data is encrypted using this method, brute force breaking of this takes n! time, where n is the total number of bits in the file. (basically, much, much higher than the probability of randomly guessing a GUID).
Assuming the GUID is well hidden within the file, a brute force attack would take a very long time to figure out.
I spent a lot of time learning about encryption on my way to this solution, and everything I read seemed to be WAY more complicated than this (and, obviously all the things I read dealt with two parties, where encryption can involve a key being passed between them).
What I learned is this:
If the key to encrypting the data is stored with the data, it's only a matter of time for someone to crack it, and get the data
There is no such thing as "perfectly secure". There are varying degrees of success in encryption, and generally speaking, when picking a method of encryption you will want to weigh the importance of the data being secure with the ease with which (considering processor and memory limitations) the data can be decrypted by your program.
I'm thinking that this is too simple to be a good solution. Can anyone prove that suspicion, and explain to me why this isn't as secure as some other methods of encryption? (or make me very happy and tell me this is pretty secure?)
These are the downsides to this algorithm that I can see right now:
The algorithm requires all of the data to be in memory (not TOO worried about this, since I'm encrypting a very small file that's ~500 bytes)
The algorithm requires changing the position of the stream reading the data in order to extract the GUID (basically you can't stream the file from the beginning to the end to decrypt it).
As a note, my application is not really of high importance, realistically it's not likely that anyone malicious will every use reflector to look at my code (realistically it's just people like me who want to know how something works, not do any harm).
This algorithm isn't going to buy you much. Someone who goes to the trouble of downloading your app and using Reflector will have your encrypted data and the code of the decryption process. They could just find your method for decrypting the data, and then use it.
The problem is that you're storing the "encryption key" in the cypher text. There is no way to make that secure when the attacker also has access to the algorithm used. Doesn't matter what crypto system you use.
The basic problem you have is that the phone application itself has to have all the information needed to decrypt and use the data, so anyone looking at the code will be able to see that.
It's the same reason that DRM schemes on DVDs, etc are routinely broken so quickly. Any device, or application, that is able to play DRM protected material has to have the means to decrypt it. Do enough poking arond in memory while the device or app is playing the content and you'll find the decryption key, and then you can crack any similiarly protected media any time you like.

Migrate C# Hash Code to PHP

I know there are similar questions already on SO but none of them seem to address this problem. I have inherited the following c# code that has been used to create password hashes in a legacy .net app, for various reasons the C# implementation is now being migrated to php:
string input = "fred";
SHA256CryptoServiceProvider provider = new SHA256CryptoServiceProvider();
byte[] hashedValue = provider.ComputeHash(Encoding.ASCII.GetBytes(input));
string output = "";
string asciiString = ASCIIEncoding.ASCII.GetString(hashedValue);
foreach ( char c in asciiString ) {
int tmp = c;
output += String.Format("{0:x2}",
(uint)System.Convert.ToUInt32(tmp.ToString()));
}
return output;
My php code is very simple but for the same input "fred" doesn't produce the same result:
$output = hash('sha256', "fred");
I've traced the problem down to an encoding issue - if I change this line in the C# code:
string asciiString = ASCIIEncoding.ASCII.GetString(hashedValue);
to
string asciiString = ASCIIEncoding.UTF7.GetString(hashedValue);
Then the php and C# output match (it yields d0cfc2e5319b82cdc71a33873e826c93d7ee11363f8ac91c4fa3a2cfcd2286e5).
Since I'm not able to change the .net code I need to work out how to replicate the results in php.
Thanks in advance for any help,
I don’t know PHP well enough to answer your question; however, I must point out that your C# code is broken. Try generating the hash of these two inputs: "âèí" and "çñÿ". You will find that their hash collides:
3f3b221c6c6e3f71223f51695d456d52223f243f3f363949443f3f763b483615
The first bug lies in this operation:
Encoding.ASCII.GetBytes(input)
This assumes that all characters within your input are US-ASCII. Any non-ASCII characters would cause the encoder to fall back to the byte value for the ? character, thereby giving (unwanted) hash collisions, as demonstrated above. Notwithstanding, this will not be an issue if your input is constrained to only allow US-ASCII characters.
The other (more severe) bug lies in the following operation:
ASCIIEncoding.ASCII.GetString(hashedValue)
ASCII only defines mappings for values 0–127. Since the elements of your hashedValue byte array may contain any byte value (0–255), encoding them as ASCII would cause data to be lost whenever a value greater than 127 is encountered. This may lead to further “unwanted” (read: potentially maliciously generated) hash collisions, even when your original input was US-ASCII.
Given that, statistically, half of the bytes constituting your hashes would be greater than 127, then you are losing at least half the strength of your hash algorithm. If a hacker gains access to your stored hashes, it is quite likely that they will manage to devise an attack to generate hash collisions by exploiting this cryptographic weakness.
Edit: Notwithstanding the considerations mentioned in my posts and Jon’s, here is the PHP code that succumbs to the same weakness – so to speak – as your C# code, and thereby gives the same hash:
$output = hash('sha256', $input, true);
for ($i = 0; $i < strlen($output); $i++)
if ($output[$i] > chr(127))
$output[$i] = '?';
$output = bin2hex($output);
Could you use mb_convert_encoding (see http://php.net/manual/en/function.mb-convert-encoding.php - the page also has a link to a list of supported encodings) to convert the PHP string to ASCII from UTF7?
I've traced the problem down to an encoding issue
Yes. You're trying to treat arbitrary binary data as if it's valid text-encoded data. It's not. You should not be using any Encoding here.
If you want the results in hex, the simplest approach is to use BitConverter.ToString
string text = BitConverter.ToString(hashedValue).Replace("-", "").ToLower();
And yes, as pointed out elsewhere, you probably shouldn't be using ASCII to convert the text to binary at the start of the hashing process. I'd probably use UTF-8.
It's really important that you understand the problem here though, as otherwise you'll run into it in other places too. You should only use encodings such as ASCII, UTF-8 etc (on any platform) when you've genuinely got encoded text data. You shouldn't use them for images, the results of cryptography, the results of hashing, etc.
EDIT: Okay, you say you can't change the C# code... it's not clear whether that just means you've got legacy data, or whether you need to keep using the C# code regardless. You should absolutey not run this code for a second longer than you have to.
But in PHP, you may find you can get away with just replacing every byte with a value >= 0x80 in the hash with 0x3F, which is the ASCII for "question mark". If you look through your data you'll probably find there are a lot of 3F bytes in there.
If you can get this to work, I would strongly suggest that you migrate over to the true MD5 hash without losing information like this. Wherever you're storing the hashes, store two: the legacy one (which is all you have now) and the rehashed one. Whenever you're asked to validate that a password is correct, you should:
Check whether you have a "new" one; if so, only use that - ignore the legacy one.
If you only have a legacy one:
Hash the password in the broken way to check whether it's correct
If it is, hash it again properly and store the results in the "new" place.
Then when everyone's logged in correctly once, you'll be able to wipe out the legacy hashes.

Iterative / Additive MD5

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.

Categories

Resources