AES Encryption in windows phone 8 - c#

I am trying to do AES Encryption in my windows phone8 app.
I searched a lot, but couldn't get a clear view to do so.
Can anybody give me link that gives the clear example of implementing AES Encryption ni WP8 App.
What i need to do is,
1)I need to pass key, initial vector, and value as strings.
2)need to encrypt that string in any format of AES Encryption, and finally need to get the encrypted value as string.
Can anybody help me.
am using this example and using UTF8 encoding for key, and Iv
myAes.Key = Encoding.UTF8.GetBytes("terr!f!cp#ssw0rdw!thonetw!st!n!t");
myAes.IV = Encoding.UTF8.GetBytes("1234567890987654");
and after encoding to convert the bytes of encrypted value to string am using ToBase64 convertion
afterText.Text = Convert.ToBase64String(encrypted);
here i need to tell my back end team, what the exact encryption am using here, am not sure about what is happening here, Can you please tell me whats that exact encryption happening here.
Thank you.

The CryptographicBuffer Class is your friend:
Use Hex or Base64 encoding for binary values you want to represent as strings. This includes Key, IV and ciphertext
Use UTF-8 for text you want to turn to bytes.

Related

How to generate a SHA256 encrypted string in C#?

For a project I need to generate a SHA256 encrypted string in C#.
The requirements are Key: todaysDate and Value: "exampleString".
How can i realize that in C#? As far as I see the SHA256-Class does not contain a property for key in C#.
SHA256 isn't an encryption algorithm, it's a hash algorithm. In other words, it's a one way function whose job is to take an input of any length and produce an output of fixed length with low collisions that's always the same for the same input. Thus, it doesn't receive a key as an input because the nature of hashing is quite different from that of encryption.
If you want to encrypt something with a key and later decrypt it by having the same key, look into symmetric encryption like AES (e.g. using the AesManaged class).
You should do your own homework. If we do it for you, you learn nothing.
Also, as Theodoros mentioned, SHA256 is a hash, not encryption. A hash is a cryptographic checksum that is used to validate or compare data. It can not be reversed into the original plaintext, which is a requirement of encryption.
How can i realize that in C#? As far as I see the SHA256-Class does not contain a property for key in C#.
Either you or the person who gave you the assignment doesn't understand what is being asked.
SHA256 doesn't have a key or a value, it only has data going in and a hash coming out. No matter how much data you run through it, the size of the hash does not change, although it's value does. You can think of a hash as a fingerprint for a particular dataset.
Maybe something like this:
public static string sha256_hash(string sValue) {
StringBuilder oResHash = new StringBuilder();
using (SHA256 oHash = SHA256Managed.Create()) {
Encoding oEnc = Encoding.UTF8;
byte[] baResult = oHash.ComputeHash(oEnc.GetBytes(sValue));
foreach (byte b in baResult)
oResHash.Append(b.ToString("x2"));
}
return oResHash.ToString();
}

Converting Laravel's AES 256 Encryptor to C#

I need to create the same results when using Crypt::Encrypt('secret') from Laravel, in C#.
I found this thread Rijndael 256 Encrypt/decrypt between c# and php?
and it seemed to be what I need, but I'm having some trouble with the third argument the, initialization vector :(.
Laravel using Rijndael AES to encrypt the data. All the user has to input is a secret key, in the config folder, that is totally random and 32 characters long.
The encyrption method looks like this:
public function encrypt($value)
{
$iv = mcrypt_create_iv($this->getIvSize(), $this->getRandomizer());
$value = base64_encode($this->padAndMcrypt($value, $iv));
// Once we have the encrypted value we will go ahead base64_encode the input
// vector and create the MAC for the encrypted value so we can verify its
// authenticity. Then, we'll JSON encode the data in a "payload" array.
$mac = $this->hash($iv = base64_encode($iv), $value);
return base64_encode(json_encode(compact('iv', 'value', 'mac')));
}
The full Encryptor.php can be found here: http://pastebin.com/yfWLPxGn
Any idea as to what I would have to input to get the same results? :)
Initialization vector is an input that is typically random. So, algorithm always creates a different value using the same input, key and the different IV. If you'd like to generate same result using both PHP and C# code, you need to use the same IV value.
Laravel's encrypt() does not return the encrypted value only. The value encrypt() generates a base64 encoded string which has json encoded values of iv, mac and encrypted value.
So the steps you need to apply in your C# encode() method:
Encode the string using the code in the link you gave.
base64_encode() the encrypted value. We will use this value in the further steps.
Create MAC (Message Authentication Code) using base64_encoded IV as the value, encrypted value as the key and sha256 as the algorithm. Take a look at this one
Now we have encrypted value, mac and iv.
Create a json string like this:
{
iv: iv value (base64 encoded),
value: encrypted value (base64 encoded),
mac: mac value created in 3rd step
}
base64 encode your this json string.
You're all set.
You would want to not apply padding and not apply any specific mode of operation. There is a pseudo-mode called ECB which basically applies the bare cipher over many blocks and applies no padding. It requires full blocks to be used.
If you don't have a full block to encrypt, you need to figure out what padding mode is used.
If that doesn't work, then you need to figure out what mode and what initialization vector is used. An initialization vector is usually prepended to a message as a unique value that varies per message, as a way to prevent some mathematical attacks on bare ciphers applied over many blocks.

Java encryption code in c#

I have the following Java code being used on an Android device that encrypts and decrypts strings using the AES encryption algorithm and an SHA1PRNG hash. I want the Android device to call a .NET WCF service written in C#. I have been searching everywhere trying to find an equivalent in C# that could encrypt and decrypt in a similar way to the Java code, but could not find the exact same way to do it. Here is the Encrypt() method in both languages:
Java:
public static String encrypt(String seed, String cleartext) throws Exception
{
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] rawKey = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(cleartext.getBytes());
return toHex(encrypted);
}
I have created something similar to this in C#, which also uses AES and SHA1:
C#:
public static string Encrypt(string seed, string cleartext)
{
var objAesCrypto = new AesManaged();
var objHashSha1 = new SHA1Managed();
var byteHash = objHashSha1.ComputeHash(Encoding.ASCII.GetBytes(seed));
var truncatedHash = new byte[16];
Array.Copy(byteHash, truncatedHash, truncatedHash.Length);
objAesCrypto.Key = truncatedHash;
objAesCrypto.Mode = CipherMode.ECB;
var byteBuff = Encoding.ASCII.GetBytes(cleartext);
return Convert.ToBase64String(objAesCrypto.CreateEncryptor().TransformFinalBlock(byteBuff, 0, byteBuff.Length));
}
There are several problems with this, however. As you can see, using C#'s version of SHA1 (SHA1Managed), it returns a hash of 20 bytes, not 16. The only way to get it to pass into the AES algorithm is to truncate the hash to 16 bytes first.
The second problem is, although both work just fine in their respective environments, when I try to pass an encrypted string from Java, along with the seed, the C# code is never able to decrypt it properly. The encrypted strings in both cases look nothing alike and are even different lengths. A typical encrypted string from the Java side looks something like this: F7E8758A2E65518FB49C53BC707288FC (32 chars long). Whereas the same exact encrypted string with the same exact seed from the C# side looks like this: 3VysgnYgNi9OJBxL2FP+rQ== (24 chars long).
I'm sure it has something to do with the fact that I'm truncating the hash in C#, but that doesn't explain why the two encrypted strings look so vastly different. (Another intersting thing I noticed is that no matter what string and seed I use on the C# side, it's always 24 chars long and ends with two equal signs - why is that?)
So, my question is, how do I get both environments to be able to decrypt each other's encrypted strings using the same seed values? I don't care if I even need to use different algorithms on the C# side than the Java side, I just need the C# code to be able to read the Java-encrypted strings.
The second problem is, although both work just fine in their respective environments, when I try to pass an encrypted string from Java, along with the seed, the C# code is never able to decrypt it properly.
You shouldn't be trying to decrypt a hash. Hashes are one-way.
A typical encrypted string from the Java side looks something like this: F7E8758A2E65518FB49C53BC707288FC (32 chars long). Whereas the same exact encrypted string with the same exact seed from the C# side looks like this: 3VysgnYgNi9OJBxL2FP+rQ== (24 chars long).
That's because you're converting to hex in Java, but to Base64 in C#:
return toHex(encrypted);
vs
return Convert.ToBase64String(...);
As for the seed length issue - again, you're doing different things in the Java vs the C#. It's not at all clear to me that using SecureRandom in that way is meant to generate the same secret key as using a straight hash from SHA1.
Rather than trying to fix this approach though, I'd suggest you should be rethinking it - it doesn't look secure to me at all. What you've called a seed is more than just a seed - it's basically a complete key. An attacker who knows the seed effectively knows the "password" to your system; you might as well just use raw bytes.
It appears that Android uses a fixed version of the SHA1PRNG. Also there seem to be many implementations for SHA1PRNG for .NET/Java/Android.
You may want to take a look at the below link for some similar problem and also a possible port of the SHA1PRNG present in Android to C#.
SHA1PRNG in Android - .NET
Your toHex(encrypted); is not the same thing as Convert.ToBase64String() as far as I know.

How to hash a password with SHA512

In my previous question I was told to hash passwords instead of encrypt, and that turned out to be correct. Problem is, I've never dealt with hashing passwords before and all the docs say SHA512 which I've tried to use on a test account to no avail. I'm not sure where to go from here. The code comments give me the example "encrypted" string as they call it, and it's "FA35A0194E3BE7024CEFB1839CBFC922" which I'm not sure how to format it like that with SHA512 since all it takes and gives back is a byte array or stream from the ComputeHash() method:
byte[] hashedPassword = HashAlgorithm.Create("SHA512").ComputeHash( ??? );
UPDATE
I've tried printing out the UTF8Encoding.GetString on the bytes, but it just displays a bunch of bullshit characters that look nothing like the one in the example docs.
Hashing with plain SHA-512 is still wrong. Use PBKDF2 which is exposed via Rfc2898DeriveBytes.
It returns raw bytes, which you should encode with either hex or base64.
You can do hex encoding with:
BitConverter.ToString(bytes).Replace("-","")
You sure it said 512 because that's 128, but anyway you could use something like
System.String Hashed = System.BitConverter.ToString(((System.Security.Cryptography.SHA512)new System.Security.Cryptography.SHA512Managed()).ComputeHash(System.Text.Encoding.ASCII.GetBytes("NotHashedPass"))).Replace("-","");
MessageBox.Show(Hashed);
but id recommend at least using a salt.
Please see tutorial here:
http://www.obviex.com/samples/hash.aspx
From the tutorial:
"These code samples demonstrate how to hash data and verify hashes. It supports several hashing algorithms. To help reduce the risk of dictionary attacks, the code prepends random bytes (so-called salt) to the original plain text before generating hashes and appends them to the generated ciphertext (original salt value will be needed for hash verification). The resulting ciphertext is base64-encoded. IMPORTANT: DATA HASHES CANNOT BE DECRYPTED BACK TO PLAIN TEXT"

RSA 2048 Whole-File Encryption (not just file contents)

I received what I thought to be a very strange requirement from a vendor for my latest project and before I go back to them asking for new requirements or clarification I thought I would bounce it off the stackoverflow crowd to make sure I wasn't completely wrong myself.
We're sending a file to a vendor with sensitive information in it. The vendor has told us that we need to encrypt the file with RSA 2048 bit encryption. I repeated the requirement 3 times to them to get clarification on exactly what they needed and each time they confirmed that simply encrypting the file contents is not what they were asking for but instead they needed me to encrypt the entire file.
My primary development language is C# and so I have looked for a way to do this using C#, then broadened my search just to find anything that would indicate how this may be done but I can't find anything. Furthermore my colleague has tried using RSA 2048 in a proof of concept to encrypt the contents of a file but is running into a character encryption limitation of 246 characters making me think it's not even possible. After the 246th character is added we get a crash error: "Key not valid for use in specified state".
Appreciate any help!
You don't normally use RSA to directly encrypt data; it's much too slow. The usual practice is to generate a random key for a fast symmetric cryptosystem, use that to encrypt the data, and use RSA to encrypt the symmetric key. That's probably why you're running into this size limit.
PGP will do what you need.
Well, your vendor understands nothing in cryptography. But if you are really willing to follow this bizarre requirements from their side... encrypt file in chunks. RSA cannot operate on content more than it's modulus size minus few bytes. IN your case it is 256 bytes minus like 11 bytes I suppose depending on padding scheme used.
Also you can do some freak CBC chaining over blocks to further increase security and without doubt your vendor will consider you a brilliant specialist after you explain him how to decrypt a file. ;) Never heard about RSA-CBC but it's an absolutely brilliant idea ;)
Whole file maybe just like zipped file, namely including directory path, filename, and file content. If your client requirement is just like that, then just zip the file and then encrypt it. You may need to increase the RSA keysize in order to do that.
UPDATE:
The following is the VB.net function to calculate the required RSA keysize. I just copy from my old project. This function assumes you are using optimal asymmetric encryption padding (OAEP):
Public Function CalculateRequireRsaKeyLength(ByRef ByteArrayToEncrypt As Byte()) As Int32
Try
Dim TotalBytesEncryptable As Int32
'TotalBytesEncryptable = ((KeyLength - 384) / 8) + 7
TotalBytesEncryptable = ByteArrayToEncrypt.Length - 7
TotalBytesEncryptable = TotalBytesEncryptable * 8
TotalBytesEncryptable = TotalBytesEncryptable + 384
If TotalBytesEncryptable <= 384 Then
Return 384
End If
If TotalBytesEncryptable >= 16384 Then
'means error
Return 0
End If
Return TotalBytesEncryptable
Catch ex As Exception
'System.IO.File.WriteAllText("e:\qqwwee.txt", ex.ToString)
Return 0
End Try
End Function
UPDATE:
Here is the link for calculating RSA keysize: how to use RSA to encrypt files (huge data) in C#

Categories

Resources