I am developing a class project in C# that encrypts the users and admins passwords. To encrypt I'm using the TripleDESCryptoServiceProvider
.
In the configuration app the user enters the key to be used for encryption and decryption of the passwords. I want to have a button to generate a key to help the user but I'm at a loss as to how I generate the 128 bits randomly. How a generate a key with 128-bits?
To generate a random value for crypto use, you should use RNGCryptoServiceProvider
:
byte[] bytes = new byte[16];
var rng = new RNGCryptoServiceProvider();
rng.GetBytes(bytes);
To turn this sequence of bytes into a string you could use hex (BitConverter.ToString
) or Base64 (Convert.ToBase64String
).
But there are some strange points here:
- 3DES uses a 168 bit key
- If you want to use symmetric encryption, you should probably use AES. 3DES isn't totally broken, but it's pretty much for legacy use only.
- Be careful about the Block cipher mode of operation you're choosing. You typically need a proper IV, a MAC and a secure chaining mode
- Often you actually should hash passwords instead of encrypting them. See How to securely hash passwords? on security.SE for details.
Take a look at the RNGCryptoServiceProvider
class, specifically the GetNonZeroBytes
method. You could run that string of bytes though a base64 encoding to make it human readable, perhaps.
I understand perfectly what you want Instead of passing urls with htttp: //mydomain.com? Id = 123, you want to pass with an encrypted value. And when someone clicks on this url with encrypted id, you want to decrypt the value of the url.
There are 2 procedures for this:
In encryption:
1 - Convert the "ID" (usually an integer) to a string. Example var NewId = Convert.ToString ((ID);
2 - Use a phrase to shuffle the encryption. Example: "I love chocolate" (this phrase can be fished from your parameter database if you have one ...)
In decryption:
1 - Use the same blocking phrase to unscramble.
2 - Convert what was decrypted to an integer again, using Convert.ToInt32 (Shuffled Variable Above)
You will have to implement 2 functions:
Function for encrypt:
private string Encrypt(string clearText)
{
string EncryptionKey = "I love chocolate";
byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
Function for Decryption:
private string Decrypt(string cipherText)
{
string EncryptionKey = "I love chocolate";
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = System.Text.Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
When encrypting an ID as ID = "123", you will have a value for the ID as ID = "B8 + iXv5 / 8BUQEbHt8 // fGA ==".
When you decrypt the ID value "B8 + iXv5 / 8BUQEbHt8 // fGA ==" you will get "123" again.
A sample in C#:
var OriginalId = 123;
var EncrypetedId = Encrypt(Convert.ToString(OriginalId));
//for recovering original value
var OriginalID = Convert.ToInt32(Decrypt(EncrypetedId));
I hope this can help you.