Reputation: 253
I have a MySQL database which is configured to receive a data with polish characters (f. ex ą, ę, ó, ł, ń etc.).
Now I want to send data with these Polish characters to a db using AES_ENCRYPT()
, and then get them from there using AES_DECRYPT()
.
My problem is that I receive a byte[] array in C# which has X elements where X is length of text I receive. And every single array element has an ASCII code of an character it represents. I could easily convert it to text using Encoding Class, but I won't get Polish characters in output text.
F. ex.:
I send AES_ENCRYPT('ąąą', '123')
to db.
I get AES_DECRYPT('sql command','123')
and I get byte[]
which has 3 elements, everyone with '97' value which represents 'aaa'
- NOT 'ąąą'
.
How to use AES_DECRYPT/ENCRYPT
in a way which allows me to send/get polish characters to my DB?!
Or how to get string output from aes_decrypt() instead byte[]?
Upvotes: 2
Views: 6159
Reputation: 15693
Your MySQL data is in characters, while encryption works on bytes. You need to convert your characters to bytes before encrypting them, and also convert the decrypted bytes back to characters. That means you need to explicitly specify the character encoding to be used at both ends so they match. The current standard is UTF-8, so you should specify that at each end. If UTF-8 does not work, then try some Microsoft specific character encoding at both ends.
Upvotes: 1
Reputation: 23685
Why don't you just implement encryption/decryption in code instead of in queries?
private static Byte[] Encrypt(String toEncrypt, Byte[] Key, Byte[] IV)
{
CryptoStream streamCrypto = null;
MemoryStream streamMemory = null;
RijndaelManaged aes = null;
StreamWriter streamWriter = null;
try
{
aes = new RijndaelManaged();
aes.Key = Key;
aes.IV = IV;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
streamMemory = new MemoryStream();
streamCrypto = new CryptoStream(streamMemory, encryptor, CryptoStreamMode.Write);
streamWriter = new StreamWriter(streamCrypto);
streamWriter.Write(toEncrypt);
}
finally
{
if (streamWriter != null)
streamWriter.Close();
if (streamCrypto != null)
streamCrypto.Close();
if (streamMemory != null)
streamMemory.Close();
if (aes != null)
aes.Clear();
}
return streamMemory.ToArray();
}
public static String Decrypt(Byte[] toDecrypt, Byte[] Key, Byte[] IV)
{
CryptoStream streamCrypto = null;
MemoryStream streamMemory = null;
RijndaelManaged aes = null;
StreamReader streamReader = null;
String output = null;
try
{
aes = new RijndaelManaged();
aes.Key = Key;
aes.IV = IV;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
streamMemory = new MemoryStream(toDecrypt);
streamCrypto = new CryptoStream(streamMemory, decryptor, CryptoStreamMode.Read);
streamReader = new StreamReader(streamCrypto);
output = streamReader.ReadToEnd();
}
finally
{
if (streamReader != null)
streamReader.Close();
if (streamCrypto != null)
streamCrypto.Close();
if (streamMemory != null)
streamMemory.Close();
if (aes != null)
aes.Clear();
}
return output;
}
In your code, you encrypt your string and then you send encrypted data to the database:
Byte[] encrypted = Encrypt(yourString, Key, IV);
When you pull out data from the database, you just get back your string using:
String decrypted = Decrypt(dbData, Key, IV);
If you don't like this way, just use your queries like so:
INSERT INTO mysecrets (mysecret1, mysecret2) VALUES (AES_ENCRYPT(secret1, YOUR_ENCRYPTION_KEY), AES_ENCRYPT(secret2, YOUR_ENCRYPTION_KEY))
SELECT AES_DECRYPT(mysecret1, YOUR_ENCRYPTION_KEY) AS secret1, AES_DECRYPT(mysecret1, YOUR_ENCRYPTION_KEY) AS secret2 FROM mysecrets
Upvotes: 1
Reputation: 672
convert using encoding might help you.
select convert(aes_decrypt(aes_encrypt('ąąą', 'abcdefg'), 'abcdefg') using UTF8);
Upvotes: 4