I need to decrypt (or encrypt original in the same way, whatever is easiest) passwords encrypted in C# by a user defined function in Coldfusion. Below is the c# function used
private static byte[] key = { };
private static byte[] IV = { 38, 55, 206, 48, 28, 64, 20, 16 };
private static string stringKey = "xxxxxxxxxxxxxxxxxxxxxxxx";
public static string Md5Encrypt(string password)
{
string empty = string.Empty;
string str;
try
{
Helpers.key = Encoding.UTF8.GetBytes(Helpers.stringKey.Substring(0, 8));
DESCryptoServiceProvider cryptoServiceProvider = new DESCryptoServiceProvider();
byte[] bytes = Encoding.UTF8.GetBytes(password.ToString());
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream((Stream) memoryStream, cryptoServiceProvider.CreateEncryptor(Helpers.key, Helpers.IV), CryptoStreamMode.Write);
cryptoStream.Write(bytes, 0, bytes.Length);
cryptoStream.FlushFinalBlock();
str = Convert.ToBase64String(memoryStream.ToArray()).Replace("+", "-").Replace("/", "_");
}
catch (Exception ex)
{
return "";
}
return str;
}
Related
I am using this code for Encrypt and Dycrpt the data using asp.net .
But i am getting the error:--
**Specified initialization vector (IV) does not match the block size for this algorithm**.
here is a code:-
my .cs file is:-
public static class Encrypt_Decrypt
{
static Encrypt_Decrypt()
{
}
public static string EncryptString(string ClearText)
{
byte[] clearTextBytes = Encoding.UTF8.GetBytes(ClearText);
System.Security.Cryptography.SymmetricAlgorithm rijn = SymmetricAlgorithm.Create();
MemoryStream ms = new MemoryStream();
byte[] rgbIV = Encoding.ASCII.GetBytes("hanuservicestalknsolve");
byte[] key = Encoding.ASCII.GetBytes("hanuservicestalknsolve");
CryptoStream cs = new CryptoStream(ms, rijn.CreateEncryptor(key, rgbIV),CryptoStreamMode.Write);
cs.Write(clearTextBytes, 0, clearTextBytes.Length);
cs.Close();
return Convert.ToBase64String(ms.ToArray());
}
private static string DecryptString(string EncryptedText)
{
byte[] encryptedTextBytes = Convert.FromBase64String(EncryptedText);
MemoryStream ms = new MemoryStream();
System.Security.Cryptography.SymmetricAlgorithm rijn = SymmetricAlgorithm.Create();
byte[] rgbIV = Encoding.ASCII.GetBytes("hanuservicestalknsolve");
byte[] key = Encoding.ASCII.GetBytes("hanuservicestalknsolve");
CryptoStream cs = new CryptoStream(ms, rijn.CreateDecryptor(key, rgbIV),
CryptoStreamMode.Write);
cs.Write(encryptedTextBytes, 0, encryptedTextBytes.Length);
cs.Close();
return Encoding.UTF8.GetString(ms.ToArray());
}
}
Here is my aspx.cs code:
string eventi = Encrypt_Decrypt.EncryptString(DataBinder.Eval(e.Item.DataItem, "name_of_post_id").ToString());
string post = Encrypt_Decrypt.EncryptString(DataBinder.Eval(e.Item.DataItem, "compreq_eventid").ToString());
From the documentation of SymmetricAlgorithm.IV:
The size of the IV property must be the same as the BlockSize property divided by 8.
I suspect you'll find that rijn.BlockSize is 128, so you should provide a 32-byte IV.
(It's not clear why your variable is called rgbIV, and you don't have any of the appropriate using statements. I hope you're not using a fixed IV and key in your real code, too... otherwise it's not providing much security.)
#user3168616: Below is the corrected code that works.
The problem was with the length of the string that you have provided for Key and rgbIV
the length of the Key and rgbIV should be of 16 bites
the code to get the length of the string in bites
Console.WriteLine(System.Text.ASCIIEncoding.ASCII.GetByteCount("abcdefghijklmnopabcdefghijklmnop"));
Modified version of your code (only change is in the string length)
class Program
{
static void Main(string[] args)
{
string strText = "this is the string";
string encryptedString = Encrypt_Decrypt.EncryptString(strText);
Console.WriteLine(encryptedString);
string decryptedString = Encrypt_Decrypt.DecryptString(encryptedString);
Console.WriteLine(decryptedString);
Console.ReadKey();
}
}
public static class Encrypt_Decrypt
{
public static string EncryptString(string ClearText)
{
byte[] clearTextBytes = Encoding.UTF8.GetBytes(ClearText);
System.Security.Cryptography.SymmetricAlgorithm rijn = SymmetricAlgorithm.Create();
MemoryStream ms = new MemoryStream();
byte[] rgbIV = Encoding.ASCII.GetBytes("abcdefghijklmnop");
byte[] key = Encoding.ASCII.GetBytes("abcdefghijklmnop");
CryptoStream cs = new CryptoStream(ms, rijn.CreateEncryptor(key, rgbIV), CryptoStreamMode.Write);
cs.Write(clearTextBytes, 0, clearTextBytes.Length);
cs.Close();
return Convert.ToBase64String(ms.ToArray());
}
public static string DecryptString(string EncryptedText)
{
byte[] encryptedTextBytes = Convert.FromBase64String(EncryptedText);
MemoryStream ms = new MemoryStream();
System.Security.Cryptography.SymmetricAlgorithm rijn = SymmetricAlgorithm.Create();
byte[] rgbIV = Encoding.ASCII.GetBytes("abcdefghijklmnop");
byte[] key = Encoding.ASCII.GetBytes("abcdefghijklmnop");
CryptoStream cs = new CryptoStream(ms, rijn.CreateDecryptor(key, rgbIV),
CryptoStreamMode.Write);
cs.Write(encryptedTextBytes, 0, encryptedTextBytes.Length);
cs.Close();
return Encoding.UTF8.GetString(ms.ToArray());
}
}
I need to pass a URL as a parameter into my querystring, since the URLs can be long I need to shorten the URL while passing and then be able to decrypt them on server side.
The URL that I am trying to pass does not contain sensitive information so string encryption techniques are not required, I am just looking to convert a long string to a short string and be able to reconstruct it back to a string.
I have tried AES encryption and it works but the resulting string is sometimes longer than the URL value itself.
Example of what I've tried so far :
private static byte[] key = { 252, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 };
private static byte[] vector = { 152, 64, 191, 111, 23, 3, 113, 119, 231, 121, 221, 112, 79, 32, 114, 156 };
private ICryptoTransform encryptor, decryptor;
private UTF8Encoding encoder;
public SimpleAES()
{
RijndaelManaged rm = new RijndaelManaged();
encryptor = rm.CreateEncryptor(key, vector);
decryptor = rm.CreateDecryptor(key, vector);
encoder = new UTF8Encoding();
}
public string Encrypt(string unencrypted)
{
return Convert.ToBase64String(Encrypt(encoder.GetBytes(unencrypted)));
}
public string Decrypt(string encrypted)
{
return encoder.GetString(Decrypt(Convert.FromBase64String(encrypted)));
}
public string EncryptToUrl(string unencrypted)
{
return HttpUtility.UrlEncode(Encrypt(unencrypted));
}
public string DecryptFromUrl(string encrypted)
{
return Decrypt(HttpUtility.UrlDecode(encrypted));
}
public byte[] Encrypt(byte[] buffer)
{
return Transform(buffer, encryptor);
}
public byte[] Decrypt(byte[] buffer)
{
return Transform(buffer, decryptor);
}
protected byte[] Transform(byte[] buffer, ICryptoTransform transform)
{
MemoryStream stream = new MemoryStream();
using (CryptoStream cs = new CryptoStream(stream, transform, CryptoStreamMode.Write))
{
cs.Write(buffer, 0, buffer.Length);
}
return stream.ToArray();
}
Example TEST :
string unencrypted = "/exampleurl/this_is_a_long_string_the_length_of_this_url_is_112_charachters_/this_string_needs_to_be-shortened/";
var result = EncryptToUrl(unencrypted);
"MHMyQdwbJpw8ah%2fbhAr2eJwTFa%2fyupemjuOVcBJmxTIdzcR0PZKCNSa5Fvi7kNrY3Kxlk5KWqAAEspWVtJfNjwwPs%2bCDGpC9Fn8CeGezWhXEbLT6CST2v%2fKpvptHVi3fBYSk1w3q1FYMx3C5DdKueQ%3d%3d"
The actual string is 112 charachters long and the result is 165 charahcters long.
The following code is taken verbatim from here. I duplicated this because the question is not a duplicate but the answer solves the problem this question poses. When you call Zip you will need to base64 encode the result to make it friendly for a browser if you plan to include it in a URL or something.
public static void CopyTo(Stream src, Stream dest) {
byte[] bytes = new byte[4096];
int cnt;
while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0) {
dest.Write(bytes, 0, cnt);
}
}
public static byte[] Zip(string str) {
var bytes = Encoding.UTF8.GetBytes(str);
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream()) {
using (var gs = new GZipStream(mso, CompressionMode.Compress)) {
//msi.CopyTo(gs);
CopyTo(msi, gs);
}
return mso.ToArray();
}
}
public static string Unzip(byte[] bytes) {
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream()) {
using (var gs = new GZipStream(msi, CompressionMode.Decompress)) {
//gs.CopyTo(mso);
CopyTo(gs, mso);
}
return Encoding.UTF8.GetString(mso.ToArray());
}
}
static void Main(string[] args) {
byte[] r1 = Zip("StringStringStringStringStringStringStringStringStringStringStringStringStringString");
string r2 = Unzip(r1);
}
This might sound strange, but can you store the querystring in a database and reference it by some primary key? That might be similar to using some third party URL shortening service.
i am using following encryption method to encrypt a string
private static byte[] mKey = { };
private static byte[] mIV = { 89, 23, 13, 17, 69, 32, 02, 79 };
private static string mStringKey = "lkj#788*";
private static string Encrypt(string pText)
{
try
{
mKey = Encoding.UTF8.GetBytes(mStringKey.Substring(0, 8));
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
Byte[] byteArray = Encoding.UTF8.GetBytes(pText);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream,
des.CreateEncryptor(mKey, mIV), CryptoStreamMode.Write);
cryptoStream.Write(byteArray, 0, byteArray.Length);
cryptoStream.FlushFinalBlock();
return Convert.ToBase64String(memoryStream.ToArray());
}
catch (Exception ex)
{
return string.Empty;
}
}
I want to build a discount code for customers with this format "CustomerId-PurchasedItem-DiscountValue" and encrypt these (CustomerId,PurchasedItem,DiscountValue) strings individually and combine encrypted values adding "-" char between them to build discount code .while decrypting above encoded string ,i will split it with "-" char,and decode individually ,but i am afraid that while encrypting if it get "-" char then my logic will fail..is this method is safe or can any one suggest me another trick?or is there any trick that encryption of a string result to fixed length?
I believe that .NET's base64 encoding will never contain a '-' character, so you should be okay.
How can I decrypt string that is encrypted with below function?
private static byte[] salt = new byte[] { 23, 21, 32, 33, 46, 59, 60, 74 };
private static int iterations = 1000;
private static int cb = 32;
public static string GetEncrypt(string plainText)
{
Rfc2898DeriveBytes k = new Rfc2898DeriveBytes(plainText, salt, iterations);
byte[] data = k.GetBytes(cb);
return Convert.ToBase64String(data);
}
You can't. You've misunderstood the purpose of Rfc2898DeriveBytes. It's not meant to be an reversible encryption algorithm - it's just meant to be a way of deriving a key which you then use within another encryption algorithm.
The idea is that you ask for a password, convert it (with a salt) into an encryption key, and use that key to encrypt the data (e.g. with TripleDES).
Then later, you ask for the password again, use the same salt to generate the same key, and then you can use that to decrypt the encrypted data.
Read RFC 2898 for more information.
public static Tuple<string, string, string> Encrypt(string encryptText)
{
byte[] bytesBuff = Encoding.Unicode.GetBytes(encryptText);
string keyValue;
string vectorValue;
using (Aes aes = Aes.Create())
{
var crypto = new Rfc2898DeriveBytes(encryptText, saltSize, iterations);
aes.Key = crypto.GetBytes(32);
aes.IV = crypto.GetBytes(16);
using var mStream = new MemoryStream();
using (var cStream = new CryptoStream(mStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
cStream.Write(bytesBuff, 0, bytesBuff.Length);
cStream.Close();
}
encryptText = Convert.ToBase64String(mStream.ToArray());
keyValue = Convert.ToBase64String(aes.Key);
vectorValue = Convert.ToBase64String(aes.IV);
}
return new Tuple<string, string, string>(encryptText, keyValue, vectorValue);
}
public static string Decrypt(string decriptText, string keyValue, string vectorValue)
{
decriptText = decriptText.Replace(" ", "+");
byte[] bytesBuff = Convert.FromBase64String(decriptText);
using (Aes aes = Aes.Create())
{
aes.Key = Convert.FromBase64String(keyValue);
aes.IV = Convert.FromBase64String(vectorValue);
using var mStream = new MemoryStream();
using (var cStream = new CryptoStream(mStream, aes.CreateDecryptor(), CryptoStreamMode.Write))
{
cStream.Write(bytesBuff, 0, bytesBuff.Length);
cStream.Close();
}
decriptText = Encoding.Unicode.GetString(mStream.ToArray());
}
return decriptText;
}
I'm try to use AES encryption for some text, but the decrypted text is not identical to original one.
Original text: abcd
Decrypted text: ?9T?o??G???x;*
Here is my code:
public static void Main(string[] args)
{
byte[] original = { 97, 98, 99, 100 }; //"abcd"
byte[] key = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
byte[] encrypt = Encrypt(original, key, iv);
byte[] decrypt = Decrypt(encrypt, key, iv);
Console.WriteLine(Encoding.UTF8.GetString(original));
Console.WriteLine(Encoding.UTF8.GetString(decrypt));
Console.ReadKey();
}
public static byte[] Encrypt(byte[] original, byte[] key, byte[] iv)
{
using (var memoryStream = new MemoryStream())
{
using (var aes = new AesManaged { Key = key, IV = iv, Padding = PaddingMode.PKCS7, Mode = CipherMode.CBC })
{
using (var cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
cryptoStream.Write(original, 0, original.Length);
}
}
return memoryStream.ToArray();
}
}
public static byte[] Decrypt(byte[] encrypt, byte[] key, byte[] iv)
{
using (var memoryStream = new MemoryStream(encrypt))
{
using (var aes = new AesManaged { Key = key, IV = iv, Padding = PaddingMode.PKCS7, Mode = CipherMode.CBC })
{
using (var cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Read))
{
byte[] decrypt = new byte[encrypt.Length];
cryptoStream.Read(decrypt, 0, decrypt.Length);
return decrypt;
}
}
}
}
What's wrong? Thanks in advance.
You've got this in your decryption code:
using (var cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(),
CryptoStreamMode.Read))
Change it to call aes.CreateDecryptor() and it works fine.
There's something wrong with your decrypt method, use something like this :
public string Decrypt(byte[] EncryptedValue)
{
#region Write the encrypted value to the decryption stream
MemoryStream encryptedStream = new MemoryStream();
CryptoStream decryptStream = new CryptoStream(encryptedStream, DecryptorTransform, CryptoStreamMode.Write);
decryptStream.Write(EncryptedValue, 0, EncryptedValue.Length);
decryptStream.FlushFinalBlock();
#endregion
#region Read the decrypted value from the stream.
encryptedStream.Position = 0;
Byte[] decryptedBytes = new Byte[encryptedStream.Length];
encryptedStream.Read(decryptedBytes, 0, decryptedBytes.Length);
encryptedStream.Close();
#endregion
return UTFEncoder.GetString(decryptedBytes);
}