Reputation: 45
I encrypt password in postgres and i want to decrypt it in c#, but two ways can not matching .How can i do that?
private static byte[] TruncateHash(string key, int length)
{
SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
// Hash the key.
byte[] keyBytes = System.Text.Encoding.Unicode.GetBytes(key);
byte[] hash = sha1.ComputeHash(keyBytes);
// Truncate or pad the hash.
Array.Resize(ref hash, length);
return hash;
}
public static string EncryptString(string plaintext, string Passphrase)
{
TripleDESCryptoServiceProvider tripleDes = new TripleDESCryptoServiceProvider();
// Initialize the crypto provider.
tripleDes.Key = TruncateHash(Passphrase, tripleDes.KeySize / 8);
tripleDes.IV = TruncateHash("", tripleDes.BlockSize / 8);
// Convert the plaintext string to a byte array.
byte[] plaintextBytes = System.Text.Encoding.Unicode.GetBytes(plaintext);
// Create the stream.
System.IO.MemoryStream ms = new System.IO.MemoryStream();
// Create the encoder to write to the stream.
CryptoStream encStream = new CryptoStream(ms, tripleDes.CreateEncryptor(), System.Security.Cryptography.CryptoStreamMode.Write);
// Use the crypto stream to write the byte array to the stream.
encStream.Write(plaintextBytes, 0, plaintextBytes.Length);
encStream.FlushFinalBlock();
// Convert the encrypted stream to a printable string.
return Convert.ToBase64String(ms.ToArray());
}
public static string DecryptString(string encryptedtext, string Passphrase)
{
TripleDESCryptoServiceProvider tripleDes = new TripleDESCryptoServiceProvider();
// Initialize the crypto provider.
tripleDes.Key = TruncateHash(Passphrase, tripleDes.KeySize / 8);
tripleDes.IV = TruncateHash("", tripleDes.BlockSize / 8);
// Convert the encrypted text string to a byte array.
byte[] encryptedBytes = Convert.FromBase64String(encryptedtext);
// Create the stream.
System.IO.MemoryStream ms = new System.IO.MemoryStream();
// Create the decoder to write to the stream.
CryptoStream decStream = new CryptoStream(ms, tripleDes.CreateDecryptor(), System.Security.Cryptography.CryptoStreamMode.Write);
// Use the crypto stream to write the byte array to the stream.
decStream.Write(encryptedBytes, 0, encryptedBytes.Length);
decStream.FlushFinalBlock();
// Convert the plaintext stream to a string.
return System.Text.Encoding.Unicode.GetString(ms.ToArray());
}
I found a way to encrypt in postgres using pgcrypto. And below is encrypt and decrypt in postgres.
SELECT encode(encrypt_iv('ABCDE121212','Key123', '','3des'), 'base64');
select decrypt_iv(decode('jEI4V5q6h5/p12NRJm666g==','base64'),'Key123','','3des')
What's wrong in my code, c# and postgres can't not matching. I want to keep c# code and change postgres code to matching
Upvotes: 3
Views: 2268
Reputation: 1606
Encrypt function:
public static String AES_encrypt(String input, string key, string Iv, int keyLength)
{
RijndaelManaged aes = new RijndaelManaged();
aes.KeySize = keyLength;
aes.BlockSize = 128;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.Key = mkey(key,keyLength);
aes.IV = mkey(Iv,128);
var encrypt = aes.CreateEncryptor(aes.Key, aes.IV);
byte[] xBuff = null;
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, encrypt, CryptoStreamMode.Write))
{
byte[] xXml = Encoding.UTF8.GetBytes(input);
cs.Write(xXml, 0, xXml.Length);
cs.FlushFinalBlock();
}
xBuff = ms.ToArray();
}
return Convert.ToBase64String(xBuff,Base64FormattingOptions.None);
}
Decrypt function:
public static String AES_decrypt(String Input, string key, string Iv, int keyLength)
{
try
{
RijndaelManaged aes = new RijndaelManaged();
aes.KeySize = keyLength;
aes.BlockSize = 128;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.Key = mkey(key,keyLength);
aes.IV = mkey(Iv,128);
var decrypt = aes.CreateDecryptor();
byte[] encryptedStr = Convert.FromBase64String(Input);
string Plain_Text;
using (var ms = new MemoryStream(encryptedStr))
{
using (var cs = new CryptoStream(ms, decrypt, CryptoStreamMode.Read))
{
using (StreamReader reader = new StreamReader(cs))
{
Plain_Text = reader.ReadToEnd();
}
}
}
return Plain_Text;
}
catch (Exception ex)
{
return null;
}
}
Helper function:
private static byte[] mkey(string skey, int keyLength)
{
int length = keyLength / 8;
byte[] key = Encoding.UTF8.GetBytes(skey);
byte[] k = GenerateEmptyArray(length);
for (int i = 0; i < key.Length; i++)
{
//k[i % 16] = (byte)(k[i % 16] ^ key[i]);
k[i] = key[i];
if(i == length-1)
break;
}
return k;
}
Variables:
input = "Hello World"
key = "NBJ42RKQ2vQoYFZO"
Iv = "j1C83921vHExVhVp"
keyLength = 128
Info about variables:
input - string that is not encrypted or encrypted. If it's encrypted it will be in Base64 format
key - Any Unicode character that will match the AES key size(in this example it's 128). I have written a function that will extract the specific length of characters and add them to a byte array
Code:
public static string PasswordFixer(string skey,int keyLength)
{
int length = keyLength / 8;
byte[] key = Encoding.UTF8.GetBytes(skey);
byte[] k = GenerateEmptyArray(length);
for (int i = 0; i < key.Length; i++)
{
k[i] = key[i];
if(i == length-1)
break;
}
return Encoding.UTF8.GetString(k);
}
Iv - it's always 128bit long meaning 16bytes. you can ignore Iv if you want, in PostgreSQL if you planing to use `encrypt` function then you can ignore the Iv by hard coding like this `aes.IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };`
keylength- This is the AES key length in this example we use 128bit meaning 16 bytes. whatever the characters that you use as the Key need to match the length of 16 bytes.
PostgreSQL
The equivalent SQL statement for the encryption and decryption is this
encrypt_iv,decrypt_iv
select convert_from(decrypt_iv(decode(tbl1.encrypted,'base64')::bytea ,'NBJ42RKQ2vQoYFZO','j1C83921vHExVhVp', 'aes-cbc/pad:pkcs'), 'UTF-8') as decrypted,tbl1.encrypted from (select encode(encrypt_iv('Hello World', 'NBJ42RKQ2vQoYFZO','j1C83921vHExVhVp', 'aes-cbc/pad:pkcs'), 'base64') as encrypted) as tbl1
encrypt,decrypt
select convert_from(decrypt(decode(tbl1.encrypted,'base64')::bytea ,'NBJ42RKQ2vQoYFZO', 'aes-cbc/pad:pkcs'), 'UTF-8') as decrypted,tbl1.encrypted from (select encode(encrypt('Hello World', 'NBJ42RKQ2vQoYFZO', 'aes-cbc/pad:pkcs'), 'base64') as encrypted) as tbl1
Upvotes: 1