In ms SQL server, I have a field text with data look like below:
"!"$$$$$$!#$$$$!!!!! !!!!!!!!!!!!!! "!! ! " !" ! !" !!!! ! !!"!".
I belive that from a plain text string, they using a Rijndael algorithm to encrypted this string. from encrypted string, it was transform to string above.
Can anyone recognize what the algorithm to decrypt from string above to the encrypted string of Rijndael algorithm?
thanks
Hi me drona please find the below code. It will useful from you.
public static class Encrypt
{
// This size of the IV (in bytes) must = (keysize / 8). Default keysize is 256, so the IV must be
// 32 bytes long. Using a 16 character string here gives us 32 bytes when converted to a byte array.
private const string initVector = "pemgail9uzpgzl88";
// This constant is used to determine the keysize of the encryption algorithm
private const int keysize = 256;
//Encrypt
public static string EncryptString(string plainText, string passPhrase)
{
byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector);
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
byte[] keyBytes = password.GetBytes(keysize / 8);
RijndaelManaged symmetricKey = new RijndaelManaged();
symmetricKey.Mode = CipherMode.CBC;
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] cipherTextBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
return Convert.ToBase64String(cipherTextBytes);
}
//Decrypt
public static string DecryptString(string cipherText, string passPhrase)
{
byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
byte[] keyBytes = password.GetBytes(keysize / 8);
RijndaelManaged symmetricKey = new RijndaelManaged();
symmetricKey.Mode = CipherMode.CBC;
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
byte[] plainTextBytes = new byte[cipherTextBytes.Length];
int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
memoryStream.Close();
cryptoStream.Close();
return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
}
enter code here
Related
I have an App in Visual Studio 2013, with password Encryptation Methods, and i need to migrate it to Xamarin Android.
The problem I had is that encryptation method in Xamarin gives a different encryptation string.
The difference is in GetBytes Method.
Here is part of my code.
public static string Encript(string ptexto, string pClave)
{
return Encript2(ptexto, pClave + "pass75dc#avz10", "s#lAvz", "MD5", 1, "#1B2c3D4e5F6g7H8", 128);
}
private static string Encript2(string textoQueEncriptaremos, string passBase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize)
{
byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
byte[] plainTextBytes = Encoding.UTF8.GetBytes(textoQueEncriptaremos);
PasswordDeriveBytes password = new PasswordDeriveBytes(passBase,saltValueBytes, hashAlgorithm, passwordIterations);
byte[] keyBytes = password.GetBytes(keySize / 8);
RijndaelManaged symmetricKey = new RijndaelManaged()
{
Mode = CipherMode.CBC
};
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes,initVectorBytes);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor,CryptoStreamMode.Write);
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] cipherTextBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
string cipherText = Convert.ToBase64String(cipherTextBytes);
return cipherText;
}
The line that make the difference is
byte[] keyBytes = password.GetBytes(keySize / 8);
I can not change my Encryptation in my c# Applicaction, Is there a way to obtain the same result in Xamarin?
From documentation you can check, it's normal you getting different byte array, GetByte() always return RANDOM key bytes. more
GetBytes(Int32) : Byte[]
Returns pseudo-random key bytes.
when i use this code to encrypt and decrypt i got an error said
Padding is invalid and cannot be removed.
any idea
public static class Crypto
{
private static readonly byte[] initVectorBytes = Encoding.ASCII.GetBytes("tu89geji340t89u2");
// This constant is used to determine the keysize of the encryption algorithm.
private const int keysize = 256;
public static string Encrypt(string plainText, string passPhrase)
{
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
{
byte[] keyBytes = password.GetBytes(keysize / 8);
using (RijndaelManaged symmetricKey = new RijndaelManaged())
{
symmetricKey.Mode = CipherMode.CBC;
using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] cipherTextBytes = memoryStream.ToArray();
return Convert.ToBase64String(cipherTextBytes);
}
}
}
}
}
}
public static string Decrypt(string cipherText, string passPhrase)
{
byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
{
byte[] keyBytes = password.GetBytes(keysize / 8);
using (RijndaelManaged symmetricKey = new RijndaelManaged())
{
symmetricKey.Mode = CipherMode.CBC;
using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes))
{
using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
byte[] plainTextBytes = new byte[cipherTextBytes.Length];
int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
}
}
}
}
}
}
}
I tried the following using your methods and it worked fine:
var passPhrase = "123456";
var e = Encrypt("testtesttesttest", passPhrase);
Console.WriteLine(e); // YEtSJshcn686ZO+JlEQ48ap/odhuvIGalbAT1XhinqQ=
var d = Decrypt(e, passPhrase);
Console.WriteLine(d); // testtesttesttest
This suggests that you're either passing a different passPhrase to Decrypt() to the one you passed to Encrypt(), or that you are somehow corrupting the ciphertext prior to decryption. (Are you perhaps calling Decrypt with the ciphertext and passphrase parameters reversed?)
It's also worth noting that essentially everything in the comments at the top of your code is wrong:
You're not passing any salt to PasswordDeriveBytes.
The size of the IV must be equal to the block size (16 bytes), it is unrelated to the key size used.
Passing a 16 character string through Encoding.ASCII.GetBytes() results in a 16 byte output, not 32 bytes. (This rather coincidentally means that your initVectorBytes is in fact the correct length for the IV).
Furthermore, PasswordDeriveBytes is deprecated and should not be used. You should be using Rfc2898DeriveBytes instead, and you should be using a proper salt value. The IV should also not be a static value, and definitely not one derived from an ASCII string!
At the moment, I'm working on a project that involves encryption. Therefore, I have a class, which worked fine in .NET 4.0, but now that I changed it so it would work in .NET 2.0, it fails to encrypt almost any string... I don't know why, but it fails every time and throws a CryptographicException. Decrypting works fine as far as I can tell, and everything else too.
Anyway, here's the code:
public class Encryption
{
static readonly string PasswordHash = "P##Sw0rd";
static readonly string SaltKey = "S#LT&KEY";
static readonly string VIKey = "#1B2c3D4e5F6g7H8";
public static string Encrypt(string plainText, string passwordHash)
{
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
byte[] keyBytes = new Rfc2898DeriveBytes(passwordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
RijndaelManaged symmetricKey = new RijndaelManaged();
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.None;
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
byte[] cipherTextBytes;
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
cipherTextBytes = memoryStream.ToArray();
cryptoStream.Close();
}
memoryStream.Close();
}
return Convert.ToBase64String(cipherTextBytes);
}
public static string Decrypt(string encryptedText, string passwordHash)
{
byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);
byte[] keyBytes = new Rfc2898DeriveBytes(passwordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
RijndaelManaged symmetricKey = new RijndaelManaged();
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.None;
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
byte[] plainTextBytes = new byte[cipherTextBytes.Length];
int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
memoryStream.Close();
cryptoStream.Close();
return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("\0".ToCharArray());
}
}
The error message is (translated from German):
CryptographicException: Length of the data to encrypt is invalid. at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) at System.Security.Cryptography.CryptoStream.FlushFinalBlock() at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing)
Encryption.Encrypt("Client connected!", "elit3Nase") does not work
"Client connected!" is not long enough to fully fill a block (16 bytes) and you are not using padding:
symmetricKey.Padding = PaddingMode.None;
Change to symmetricKey.Padding = PaddingMode.PKCS7; to ensure padding is applied.
I try to decrypt request params for JDownloader CNL Feature.
http://jdownloader.org/knowledge/wiki/glossary/cnl2
In this sample the iv and the key is '31323334353637383930393837363534' and i try to decrypt this value 'DRurBGEf2ntP7Z0WDkMP8e1ZeK7PswJGeBHCg4zEYXZSE3Qqxsbi5EF1KosgkKQ9SL8qOOUAI'
The php code in sample to encrypt is the following
I know i need to decode the key from hex to string, that means the correct key is 1234567890987654
function base16Encode($arg){
$ret="";
for($i=0;$i<strlen($arg);$i++){
$tmp=ord(substr($arg,$i,1));
$ret.=dechex($tmp);
}
return $ret;
}
$key="1234567890987654";
$transmitKey=base16Encode($key);
$link="http://rapidshare.com/files/285626259/jDownloader.dmg\r\nhttp://rapidshare.com/files/285622259/jDownloader2.dmg";
$cp = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', '');
#mcrypt_generic_init($cp, $key,$key);
$enc = mcrypt_generic($cp, $link);
mcrypt_generic_deinit($cp);
mcrypt_module_close($cp);
$crypted=base64_encode($enc);
echo $crypted;
My last try to decrypt is the following c# code but i have some troble with lenght of input.
public static String DecryptRJ(string input, string iv, string key )
{
key = key.DecodeBase16(); // Extension method
byte[] initVectorBytes = Encoding.UTF8.GetBytes(iv);
byte[] cipherTextBytes = Encoding.UTF8.GetBytes(input);
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
RijndaelManaged symmetricKey = new RijndaelManaged();
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.BlockSize = 256;
symmetricKey.KeySize = 256;
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
byte[] plainTextBytes = new byte[cipherTextBytes.Length];
int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
memoryStream.Close();
cryptoStream.Close();
return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
}
One more Information this PHP Code works fine and can decode and decrypt correct.
function decrypt($data, $_key){
echo '<br><hr><br>';
out($data);
$plain=base64_decode($data);
out($plain);
echo 'init';
//$e = mcrypt_decrypt ( $_cp , $_key , $plain , 'cbc' );
$e = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $_key, $plain, 'cbc', $_key);
out($e);
echo 'end';
}
Ok now i can decrypt the encrypted sample data (see php code or http://jdownloader.org/knowledge/wiki/glossary/cnl2) Code C# is this
public static string DecryptDLCData(string data, string _key, Encoding encoding = null)
{
if (encoding == null)
encoding = Encoding.Default;
data = data.DecodeBase64(encoding);
RijndaelManaged rijndaelCipher = new RijndaelManaged();
rijndaelCipher.Mode = CipherMode.CBC;
rijndaelCipher.Padding = PaddingMode.Zeros;
rijndaelCipher.KeySize = 256;
rijndaelCipher.BlockSize = 128;
byte[] pwdBytes = Encoding.Default.GetBytes(_key);
byte[] keyBytes = new byte[16];
int len = pwdBytes.Length;
if (len > keyBytes.Length) len = keyBytes.Length;
Array.Copy(pwdBytes, keyBytes, len);
rijndaelCipher.Key = keyBytes;
rijndaelCipher.IV = keyBytes;
var transform = rijndaelCipher.CreateDecryptor();
byte[] plainText = Encoding.Default.GetBytes(data);
byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);
return Encoding.UTF8.GetString(cipherBytes);
}
Why can I encrypt only 16 characters of text?
Works:
string plainText = "1234567890123456";
Doesn't work:
string plainText = "12345678901234561";
Doesn't work:
string plainText = "123456789012345";
Code:
string plainText = "1234567890123456";
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
byte[] keyBytes = System.Text.Encoding.UTF8.GetBytes("1234567890123456");
byte[] initVectorBytes = System.Text.Encoding.UTF8.GetBytes("1234567890123456");
RijndaelManaged symmetricKey = new RijndaelManaged();
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.Zeros;
ICryptoTransform encryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] cipherTextBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
string cipherText = Convert.ToBase64String(cipherTextBytes);
Console.ReadLine();
Not sure I understand the question, but looking at what I assume the intent is of the code the following
symmetricKey.CreateDecryptor
Should probably be
symmetricKey.CreateEncryptor
Probably because AES is a block cipher with 128 bits per block.. maybe you just need to add a padding such that length % 128 == 0.
(I'm not a C# developer but it can happen that an implementation doesn't care about adding padding by itself)
Just a hint: try if it works with 256 bits