I have a service named CryptoService which inherit the interface ICryptoService that consist of 2 method Crypto Decrypto function.
Encryption of a string is Working but the Decryption of hash result will return my key instead of the Decrypted string.
Here is my encryption code :
private string _salt = "*1234567890!##$%^&*()14344*";
private string Crypto(string text)
{
var hashmd5 = new MD5CryptoServiceProvider();
byte[] toEncryptArray = Encoding.UTF8.GetBytes(_salt);
byte[] keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(_salt));
hashmd5.Clear();
TripleDesProvider.Key = keyArray;
TripleDesProvider.Mode = CipherMode.ECB;
TripleDesProvider.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = TripleDesProvider.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
My decryption code :
private string Decrypto(string text)
{
try
{
var hashmd5 = new MD5CryptoServiceProvider();
byte[] toEncryptArray = Convert.FromBase64String(text);
byte[] keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(_salt));
hashmd5.Clear();
TripleDesProvider.Key = keyArray;
TripleDesProvider.Mode = CipherMode.ECB;
TripleDesProvider.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = TripleDesProvider.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
TripleDesProvider.Clear();
return Encoding.UTF8.GetString(resultArray);
//return Encoding.UTF8.GetString(resultArray);
}
catch
{
return string.Empty;
}
}
provided here the screenshot in action.
here are the references of my codes I found in the internet
https://www.codeproject.com/Articles/14150/Encrypt-and-Decrypt-Data-with-C
This cannot work. A hash, such as MD5, is one-way. You cannot get the original text from the hash value.
If your crypto service runs on the same machine, I suggest using the Data Protection class.
Your toEncryptArray in Encrypto gets the value _salt. You meant text.
So, good news, your decryption works.
I did some encryption using PHP in my Database and would normally decrypt using:
$encrypt_method = "AES-256-CBC";
$secret_key = "testing";
$secret_iv = "testingyes!!!";
$key = hash('sha256', $secret_key); // hash the key
$iv = substr(hash('sha256', $secret_iv), 0, 16); // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
echo(openssl_decrypt(base64_decode($data), $encrypt_method, $key, 0, $iv)); // the decrypted data
I'm trying to do the same task but with C# 2013 to decrypt the same data, any ideas?
I would encrypt in php using:
$encrypt_method = "AES-256-CBC";
$secret_key = "testing";
$secret_iv = "testingyes!!!";
$key = hash('sha256', $secret_key); // hash the key
$iv = substr(hash('sha256', $secret_iv), 0, 16); // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
echo(base64_encode(openssl_encrypt($data, $encrypt_method, $key, 0, $iv))); // the encrypted data
encrypting: this is a test
gives: d0EzQ2MvMHkxRks2cXg5NkFkK2twZz09=
I tried this in C#:
public static String sha256_hash(String value)
{
StringBuilder Sb = new StringBuilder();
using (SHA256 hash = SHA256Managed.Create())
{
Encoding enc = Encoding.UTF8;
Byte[] result = hash.ComputeHash(enc.GetBytes(value));
foreach (Byte b in result)
Sb.Append(b.ToString("x2"));
}
return Sb.ToString();
}
private static String AES_decrypt(String Input)
{
RijndaelManaged aes = new RijndaelManaged();
aes.KeySize = 256;
aes.BlockSize = 256;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.None;
aes.Key = Convert.FromBase64String(sha256_hash("testing"));
aes.IV = Convert.FromBase64String(sha256_hash("testingyes!!!").Substring(0, 16));
var decrypt = aes.CreateDecryptor();
byte[] xBuff = null;
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, decrypt, CryptoStreamMode.Write))
{
byte[] xXml = Convert.FromBase64String(Input);
cs.Write(xXml, 0, xXml.Length);
}
xBuff = ms.ToArray();
}
String Output = Encoding.UTF8.GetString(xBuff);
return Output;
}
string cipherData = "d0EzQ2MvMHkxRks2cXg5NkFkK2twZz09=";
string f = AES_decrypt(cipherData);
Console.Write(f);
But I'm getting error: specified key is not a valid size for this algorithm
However the key I'm using is working when I use PHP
RijndaelManaged aes = new RijndaelManaged();
aes.KeySize = 256;
aes.BlockSize = 256;
Block size should be 128 to be compatible with AES-256-CBC.
Rijndael supports variable block sizes - AES does not.
Hi there i'm using this encryption method to encrypt my json value in .net side
public static string Encrypt256(string text)
{
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.BlockSize = 128;
aes.KeySize = 256;
aes.IV = Encoding.UTF8.GetBytes(AesIV256);
aes.Key = Encoding.UTF8.GetBytes(AesKey256);
aes.Mode = CipherMode.CBC;
byte[] src = Encoding.Unicode.GetBytes(text);
using (ICryptoTransform encrypt = aes.CreateEncryptor())
{
byte[] dest = encrypt.TransformFinalBlock(src, 0, src.Length);
Debug.WriteLine(Convert.ToBase64String(dest));
return Convert.ToBase64String(dest);
}
}
And im trying to decrypt it in Node Js side
var crypto = require('crypto'),
algorithm = process.env.tombalaCryptoAlgorithm,
password = process.env.tombalaHmacPass,
iv = '!QAZ2WSX#EDC4RFV'
function encrypt(text) {
var cipher = crypto.createCipheriv(algorithm, password, iv)
var encrypted = cipher.update(text, 'utf8', 'base64')
encrypted += cipher.final('base64');
return encrypted;
You are converting your text to be encrypted to Unicode which means UTF-16.
In UTF-16 every character consists of two bytes. If the second byte is not used it is null as you have observed.
I assume you want UTF-8 encoding. Therefore replace the line
byte[] src = Encoding.Unicode.GetBytes(text);
with
byte[] src = Encoding.UTF8.GetBytes(text);
I have an encrypted database in which the strings are values like the below:
ùœ¢Qa³•ù¼?-pJ´’ˆò»Æ8-skYIÞµ§¬†Œ‚„Šç
ù¢=~Òñ€Ï?-pJ´’ˆò»Æ8-skYIÞµ§¬†Œ‚„Šç
XwÚûùÖP^opJ´’ˆò»Æ8-skYIÞµ§¬†Œ‚„Šç
ö‘±_|Çúùß^_f9´’ˆò»Æ8-skYIÞµ§¬†Œ‚„Šç
I'm trying different ways to dencrypt the information (it's a simmetric encryption and I have the key, but I don't know the algorithm, more detail here How to decrypt a string encrypted by V FoxPro)
When I tried different ways to dencrypt using C#.NET in an step I get àn error saying that "the string has a non-base64 character" in the following line:
Convert.FromBase64String(input)
Where input is a string similar to the one I share above.
How Can I receive an string like that from DB in order to work with that in C#?
I normally use something like this:
public static class EncryptDecryptString
{
public static string Encrypt(string input, string key)
{
byte[] inputArray = UTF8Encoding.UTF8.GetBytes(input);
TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
tripleDES.Key = UTF8Encoding.UTF8.GetBytes(key);
tripleDES.Mode = CipherMode.ECB;
tripleDES.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tripleDES.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
tripleDES.Clear();
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
public static string Decrypt(string input, string key)
{
byte[] inputArray = Convert.FromBase64String(input);
TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
tripleDES.Key = UTF8Encoding.UTF8.GetBytes(key);
tripleDES.Mode = CipherMode.ECB;
tripleDES.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tripleDES.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
tripleDES.Clear();
return UTF8Encoding.UTF8.GetString(resultArray);
}
}
I have the following encryption method. I am not able to decrypt it. I have inherited the encryption algorithm so it cannot be changed.
public static string Encrypt(string plaintext)
{
byte[] rgbIV;
byte[] key;
RijndaelManaged rijndael = BuildRigndaelCommon(out rgbIV, out key);
//convert plaintext into a byte array
byte[] plaintextBytes = Encoding.UTF8.GetBytes(plaintext);
int BlockSize;
BlockSize = 16 * (1 + (plaintext.Length / 16));
Array.Resize(ref plaintextBytes, BlockSize);
// fill the remaining space with 0
for (int i = plaintext.Length; i < BlockSize; i++)
{
plaintextBytes[i] = 0;
}
byte[] cipherTextBytes = null;
//create uninitialized Rijndael encryption obj
using (RijndaelManaged symmetricKey = new RijndaelManaged())
{
//Call SymmetricAlgorithm.CreateEncryptor to create the Encryptor obj
var transform = rijndael.CreateEncryptor();
//Chaining mode
symmetricKey.Mode = CipherMode.CFB;
//create encryptor from the key and the IV value
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(key, rgbIV);
//define memory stream to hold encrypted data
using (MemoryStream ms = new MemoryStream())
{
//define cryptographic stream - contains the transformation key to be used and the mode
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
//encrypt contents of cryptostream
cs.Write(plaintextBytes, 0, BlockSize);
cs.FlushFinalBlock();
//convert encrypted data from a memory stream into a byte array
cipherTextBytes = ms.ToArray();
}
}
}
//store result as a hex value
string hexOutput = BitConverter.ToString(cipherTextBytes).Replace("-", "");
hexOutput = hexOutput.Substring(0, plaintext.Length * 2);
//finially return encrypted string
return hexOutput;
}
As you can see it's pretty standard except at the end it's converted to hex and substring is performed. I'm having great difficulty doing the opposite.
My decrypt method is like:
public static string Decrypt(string disguisedtext)
{
byte[] rgbIV;
byte[] key;
BuildRigndaelCommon(out rgbIV, out key);
byte[] disguishedtextBytes = FromHexString(disguisedtext);
string visiabletext = "";
//create uninitialized Rijndael encryption obj
using (var symmetricKey = new RijndaelManaged())
{
//Call SymmetricAlgorithm.CreateEncryptor to create the Encryptor obj
symmetricKey.Mode = CipherMode.CFB;
//create encryptor from the key and the IV value
// ICryptoTransform encryptor = symmetricKey.CreateEncryptor(key, rgbIV);
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(key, rgbIV);
//define memory stream to hold encrypted data
using (MemoryStream ms = new MemoryStream(disguishedtextBytes))
{
//define cryptographic stream - contains the transformation to be used and the mode
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
{
byte[] plaintextBytes = new Byte[disguishedtextBytes.Length];
cs.Write(disguishedtextBytes, 0, disguishedtextBytes.Length);
cs.FlushFinalBlock();
//convert decrypted data from a memory stream into a byte array
byte[] visiabletextBytes = ms.ToArray();
visiabletext = Encoding.UTF8.GetString(visiabletextBytes);
}
}
}
return visiabletext;
}
Helper Methods:
private static RijndaelManaged BuildRigndaelCommon(out byte[] rgbIV, out byte[] key)
{
rgbIV = new byte[] { 0x0, 0x1, 0x2, 0x3, 0x5, 0x6, 0x7, 0x8, 0xA, 0xB, 0xC, 0xD, 0xF, 0x10, 0x11, 0x12 };
key = new byte[] { 0x0, 0x1, 0x2, 0x3, 0x5, 0x6, 0x7, 0x8, 0xA, 0xB, 0xC, 0xD, 0xF, 0x10, 0x11, 0x12 };
//Specify the algorithms key & IV
RijndaelManaged rijndael = new RijndaelManaged{BlockSize = 128, IV = rgbIV, KeySize = 128, Key = key, Padding = PaddingMode.None};
return rijndael;
}
public static byte[] FromHexString(string hexString)
{
if (hexString == null)
{
return new byte[0];
}
var numberChars = hexString.Length;
var bytes = new byte[numberChars / 2];
for (var i = 0; i < numberChars; i += 2)
{
bytes[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16);
}
return bytes;
}
I'm getting various errors regarding the length of the string and that the padding is invalid. Has anybody any ideas to get the decryption working. I've tried padding out the input string back to 32 bytes but no avail.
Your problem is a subtle error in your Encrypt method. You are losing data from your returned ciphertext by messing with the the hexOutput string. Instead of:
//store result as a hex value
string hexOutput = BitConverter.ToString(cipherTextBytes).Replace("-", "");
hexOutput = hexOutput.Substring(0, plaintext.Length * 2);
//finially return encrypted string
return hexOutput;
You should just return the output:
return BitConverter.ToString(cipherTextBytes).Replace("-", "");
You will also need to change the padding mode in your Decrypt method to None. Though this will now correctly decrypt it will also include the manual padding characters that you add in your encrypt method. As you don't know your plain text you have no GOOD way of removing them. You could always add a method to remove all bytes in your array that dont match your padding value of zero:
int endMarker = decryptedData.Length;
do { endMarker--; } while (decryptedData[endMarker] == 0);
Array.Resize(ref decryptedData, endMarker + 1);
However this isn't really a good idea as you're possibly discarding otherwise valid data. A better solution would be to update your encrypt and decrypt methods to let the cipher handle the padding. Putting it all together we get (showing only what i've changed):
private static RijndaelManaged BuildRigndaelCommon(out byte[] rgbIV, out byte[] key)
{
rgbIV = new byte[] { 0x0, 0x1, 0x2, 0x3, 0x5, 0x6, 0x7, 0x8, 0xA, 0xB, 0xC, 0xD, 0xF, 0x10, 0x11, 0x12 };
key = new byte[] { 0x0, 0x1, 0x2, 0x3, 0x5, 0x6, 0x7, 0x8, 0xA, 0xB, 0xC, 0xD, 0xF, 0x10, 0x11, 0x12 };
//Specify the algorithms key & IV
RijndaelManaged rijndael = new RijndaelManaged{BlockSize = 128, IV = rgbIV, KeySize = 128, Key = key, Padding = PaddingMode.PKCS7 };
return rijndael;
}
public static string Encrypt(string plaintext)
{
byte[] rgbIV;
byte[] key;
RijndaelManaged rijndael = BuildRigndaelCommon(out rgbIV, out key);
//convert plaintext into a byte array
byte[] plaintextBytes = Encoding.UTF8.GetBytes(plaintext);
byte[] cipherTextBytes = null;
//create uninitialized Rijndael encryption obj
using (RijndaelManaged symmetricKey = new RijndaelManaged())
{
//Call SymmetricAlgorithm.CreateEncryptor to create the Encryptor obj
var transform = rijndael.CreateEncryptor();
//Chaining mode
symmetricKey.Mode = CipherMode.CFB;
//create encryptor from the key and the IV value
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(key, rgbIV);
//define memory stream to hold encrypted data
using (MemoryStream ms = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
//encrypt contents of cryptostream
cs.Write(plaintextBytes, 0, plaintextBytes.Length);
cs.Flush();
cs.FlushFinalBlock();
//convert encrypted data from a memory stream into a byte array
ms.Position = 0;
cipherTextBytes = ms.ToArray();
ms.Close();
cs.Close();
}
}
//store result as a hex value
return BitConverter.ToString(cipherTextBytes).Replace("-", "");
}
public static string Decrypt(string disguisedtext)
{
byte[] disguishedtextBytes = FromHexString(disguisedtext);
byte[] rgbIV;
byte[] key;
BuildRigndaelCommon(out rgbIV, out key);
string visiabletext = "";
//create uninitialized Rijndael encryption obj
using (var symmetricKey = new RijndaelManaged())
{
//Call SymmetricAlgorithm.CreateEncryptor to create the Encryptor obj
symmetricKey.Mode = CipherMode.CFB;
symmetricKey.BlockSize = 128;
//create encryptor from the key and the IV value
// ICryptoTransform encryptor = symmetricKey.CreateEncryptor(key, rgbIV);
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(key, rgbIV);
//define memory stream to hold encrypted data
using (MemoryStream ms = new MemoryStream(disguishedtextBytes))
{
//define cryptographic stream - contains the transformation to be used and the mode
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
byte[] decryptedData = new byte[disguishedtextBytes.Length];
int stringSize = cs.Read(decryptedData, 0, disguishedtextBytes.Length);
cs.Close();
//Trim the excess empty elements from the array and convert back to a string
byte[] trimmedData = new byte[stringSize];
Array.Copy(decryptedData, trimmedData, stringSize);
visiabletext = Encoding.UTF8.GetString(trimmedData);
}
}
}
return visiabletext;
}
Hope this helps point you on your way. As an aside I maintain a set of encryption utilities on Snipt that may be of use to you, particularly the SymmetricEncrypt and SymmetricDecrypt methods.
------ EDIT ------
As noted in the comment below, we are not allowed to alter the Encrypt method. I do like a good challenge! With appropriate byte mangling applied, here's a decrypt that honours the return coming form the Encrypt method:
public static string Decrypt(string disguisedtext)
{
byte[] disguishedtextBytes = FromHexString(disguisedtext);
var originalLength = disguishedtextBytes.Length;
int BlockSize;
BlockSize = 16 * (1 + (originalLength / 16));
Array.Resize(ref disguishedtextBytes, BlockSize);
// fill the remaining space with 0
for (int i = originalLength; i < BlockSize; i++)
{
disguishedtextBytes[i] = 0;
}
byte[] rgbIV;
byte[] key;
BuildRigndaelCommon(out rgbIV, out key);
string visiabletext = "";
//create uninitialized Rijndael encryption obj
using (var symmetricKey = new RijndaelManaged())
{
//Call SymmetricAlgorithm.CreateEncryptor to create the Encryptor obj
symmetricKey.Mode = CipherMode.CFB;
symmetricKey.BlockSize = 128;
symmetricKey.Padding = PaddingMode.None;
// ICryptoTransform encryptor = symmetricKey.CreateEncryptor(key, rgbIV);
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(key, rgbIV);
//define memory stream to hold encrypted data
using (MemoryStream ms = new MemoryStream(disguishedtextBytes))
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
byte[] decryptedData = new byte[disguishedtextBytes.Length];
int stringSize = cs.Read(decryptedData, 0, disguishedtextBytes.Length);
cs.Close();
//Trim the excess empty elements from the array and convert back to a string
byte[] trimmedData = new byte[stringSize];
Array.Copy(decryptedData, trimmedData, originalLength);
Array.Resize(ref trimmedData, originalLength);
visiabletext = Encoding.UTF8.GetString(trimmedData);
}
}
return visiabletext;
}
It looks like your encryption method outputs a space separated hex string, representing a byte array: "OA FE 82 3B ...". It also makes assumptions about the plaintext and chops off any padding.
Your first step it to convert the hex string back into a byte array, which is pretty easy.
To deal with the lost padding just set decryption to NoPadding, as #Wolfwyrd suggests. You may have to check that your data is correctly terminated if the padding length was off.
If the assumptions about plaintext characters were wrong, then it is likely you will have to recover things by hand. If the plaintext is strict ASCII (7 bit characters only) then this should not be a problem. Anything outside that, such as accented letters: á, é etc. will break the assumption.