Get same encrypted string from System.Security.Cryptography - c#

I want to make change in below encryption code so it gives me same encrypted string for a given text again and again.
e.g input string : "test"
output encrypted string : "##$##$##$SDFDSF"
If I input "test" again and again output should be same.
public static string Encrypt(string text, bool encryptSame = false)
{
var key = Encoding.UTF8.GetBytes("E546C8DF278CD5931069B522E695D4F3");
using (var aesAlg = Aes.Create())
{
if (encryptSame)
{
aesAlg.Padding = PaddingMode.Zeros;
aesAlg.Mode = CipherMode.ECB;
}
using (var encryptor = aesAlg.CreateEncryptor(key, aesAlg.IV))
{
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(text);
}
var iv = aesAlg.IV;
var decryptedContent = msEncrypt.ToArray();
var result = new byte[iv.Length + decryptedContent.Length];
Buffer.BlockCopy(iv, 0, result, 0, iv.Length);
Buffer.BlockCopy(decryptedContent, 0, result, iv.Length, decryptedContent.Length);
return Convert.ToBase64String(result);
}
}
}
}

Related

how to use openssl_decrypt using hex as key?

i want to decrypt an encrypted string using openssl in PHP,
the string is encrypted in C# using this code:
private static MemoryStream MsEncrypt = null;
private static CryptoStream CsEncrypt = null;
public static string EncryptStringToBytes(string plainText, byte[] key)
{
using (var rijndaelConfig = new RijndaelManaged())
{
rijndaelConfig.Key = key;
rijndaelConfig.Mode = CipherMode.CBC;
rijndaelConfig.BlockSize = 128;
rijndaelConfig.Padding = PaddingMode.Zeros;
rijndaelConfig.GenerateIV();
var encryptor = rijndaelConfig.CreateEncryptor(rijndaelConfig.Key,
rijndaelConfig.IV);
byte[] encrypted;
try
{
MsEncrypt = new MemoryStream();
CsEncrypt = new CryptoStream(MsEncrypt, encryptor, CryptoStreamMode.Write);
using (var swEncrypt = new StreamWriter(CsEncrypt))
{
swEncrypt.AutoFlush = true;
swEncrypt.Write(plainText);
}
encrypted = MsEncrypt.ToArray();
byte[] result = new byte[rijndaelConfig.IV.Length + encrypted.Length];
rijndaelConfig.IV.CopyTo(result, 0);
encrypted.CopyTo(result, rijndaelConfig.IV.Length);
return Uri.EscapeDataString(Convert.ToBase64String(result));
}
finally
{
if (MsEncrypt != null)
{
MsEncrypt.Dispose();
}
if (CsEncrypt != null)
{
CsEncrypt.Dispose();
}
}
}
}
this is my key: "2b8958eb1da990c039933a504259059fc9c8a893447fcbb3a8c504797e637288"
and this is my string: "hello[[]]there!"
and this is the encrypted value "O0wTQerC%2FQs5sFUMc3uXoSkrsJcY7toWqlsQYRYAD64%3D"
here is a working encrypt and decrypt function in fiddle (C#): https://dotnetfiddle.net/9BKh5J
this is what ive tried so far in php to encrypt this:
function decrypt($text,$key){
$encrypted = base64_decode($text);
$key = unpack('C*', $key);
$key = implode('',$key);
$decrypted = openssl_decrypt($encrypted, 'aes-128-cbc', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING );
return rtrim($decrypted, "\0");
}
here is the php fiddle: https://paiza.io/projects/zwXd611Gw5snUclFMjebEw
but i get an empty string, any idea why?

"Padding is invalid and cannot be removed" Error while decrypting cipher text Using Aes

I want to encrypt/ decrypt my access token using Aes. Encryption part is successful working. But my problem is when decrypting the encrypted access token following error is occurred
Padding is invalid and cannot be removed.
Following line is throwing an exception:
using (var srDecrypt = new StreamReader(csDecrypt))
{
result = srDecrypt.ReadToEnd();
}
Can anyone tell me what I can do to solve this issue? (as a console application)
class Program
{
private static string keyString = "E546C8DF278CD5931069B522E695D4F2";
static void Main(string[] args)
{
var text = "a16df7367e9eca23ac5e071dc4449a7a";
Console.WriteLine(EncryptString(text)); ;
Console.WriteLine(DecryptString(EncryptString(text)));
Console.ReadLine();
}
public static string EncryptString(string text)
{
var key = Encoding.UTF8.GetBytes(keyString);
using (var aesAlg = Aes.Create())
{
using (var encryptor = aesAlg.CreateEncryptor(key, aesAlg.IV))
{
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(text);
}
var iv = aesAlg.IV;
var decryptedContent = msEncrypt.ToArray();
var result = new byte[iv.Length + decryptedContent.Length];
Buffer.BlockCopy(iv, 0, result, 0, iv.Length);
Buffer.BlockCopy(decryptedContent, 0, result, iv.Length, decryptedContent.Length);
return Convert.ToBase64String(result);
}
}
}
}
public static string DecryptString(string cipherText)
{
var fullCipher = Convert.FromBase64String(cipherText);
var iv = new byte[16];
var cipher = new byte[16];
Buffer.BlockCopy(fullCipher, 0, iv, 0, iv.Length);
Buffer.BlockCopy(fullCipher, iv.Length, cipher, 0, iv.Length);
var key = Encoding.UTF8.GetBytes(keyString);
using (var aesAlg = Aes.Create())
{
using (var decryptor = aesAlg.CreateDecryptor(key, iv))
{
string result;
using (var msDecrypt = new MemoryStream(cipher))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
result = srDecrypt.ReadToEnd();
}
}
}
return result;
}
}
}
}
You should change it
var iv = new byte[16];
var cipher = new byte[16];
Buffer.BlockCopy(fullCipher, 0, iv, 0, iv.Length);
Buffer.BlockCopy(fullCipher, iv.Length, cipher, 0, iv.Length);
to
var iv = new byte[16];
var cipher = new byte[fullCipher.Length - 16]; //Calculate correct byte size
Buffer.BlockCopy(fullCipher, 0, iv, 0, iv.Length);
Buffer.BlockCopy(fullCipher, iv.Length, cipher, 0, cipher.Length); //Change destination count of copied bytes
Cipher array size can't be 16 bytes by default you should calculate it.

Specified padding mode is not valid for this algorithm - c# - System.Security.Cryptography

pretty new to c# and currently having a problem decrypting long passwords with an error of
Specified key is not a valid size for this algorithm
I know this has something to do with the encrypted password bits length not being supported but unsure how to go about suggested ways to allow for these longer passwords.
Here's my encrypt and decrypt
"cipherKey": "0123456789abcdef", "cipherVector":
"somereallycooliv"
using System;
using System.Security.Cryptography;
using System.IO;
using System.Text;
namespace DataApi
{
public class Encryption
{
private readonly IConfigurationService _configService;
private const string _vector = "cipherVector";
private const string _key = "cipherKey";
public Encryption(IConfigurationService configService)
{
_configService = configService;
}
public string EncryptString(string text)
{
if(string.IsNullOrEmpty(text))
{
return "";
}
try
{
var key = Encoding.UTF8.GetBytes(_configService.Get(_key));
byte[] IV = Encoding.ASCII.GetBytes(_configService.Get(_vector));
using (var aesAlg = Aes.Create())
{
using (var encryptor = aesAlg.CreateEncryptor(key, IV))
{
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(text);
}
var decryptedContent = msEncrypt.ToArray();
var result = new byte[IV.Length + decryptedContent.Length];
Buffer.BlockCopy(IV, 0, result, 0, IV.Length);
Buffer.BlockCopy(decryptedContent, 0, result, IV.Length, decryptedContent.Length);
return Convert.ToBase64String(result);
}
}
}
}
catch(Exception e) {
Loggifer.Error("Unable to encrypt string: "+text , e );
throw e;
}
}
public string DecryptString(string cipherText)
{
if(string.IsNullOrEmpty(cipherText))
{
return "";
}
try
{
var fullCipher = Convert.FromBase64String(cipherText);
byte[] IV = Encoding.ASCII.GetBytes(_configService.Get(_vector));
var cipher = new byte[16];
Buffer.BlockCopy(fullCipher, 0, IV, 0, IV.Length);
Buffer.BlockCopy(fullCipher, IV.Length, cipher, 0, IV.Length);
var key = Encoding.UTF8.GetBytes(_configService.Get(_key));
using (var aesAlg = Aes.Create())
{
using (var decryptor = aesAlg.CreateDecryptor(key, IV))
{
string result;
using (var msDecrypt = new MemoryStream(cipher))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
result = srDecrypt.ReadToEnd();
}
}
}
return result;
}
}
}
catch (Exception e)
{
Loggifer.Error("Unable to decrypt string: "+cipherText , e );
throw e;
}
}
}
}
Two changes are required in the function public string DecryptString(string cipherText)
var cipher = new byte[fullCipher.Length - IV.Length];
and
Buffer.BlockCopy(fullCipher, IV.Length, cipher, 0, fullCipher.Length - IV.Length);

Error AES - Standard SymmetricAlgorithm, “Padding is invalid and cannot be removed”

I am using AES - Standard SymmetricAlgorithm, for Encrypting and Decrypting string. String is encrypting successfully but when it comes to decrypt the compiler gives me the exception i.e
“Padding is invalid and cannot be removed”.
I have created a demo console application for testing, please have a look on below code.
The Main Method:
static void Main(string[] args)
{
var content = "5466160057107706";
var key = "E546C8DF278CD5931069B522E695D4F2";
var encrypted = EncryptString(content, key);
Console.WriteLine(encrypted);
var decrypted = DecryptString(encrypted, key);
Console.WriteLine(decrypted);
Console.ReadLine();
}
Method added for Encryption:
public static string EncryptString(string text, string keyString)
{
var key = Encoding.UTF8.GetBytes(keyString);
using (var aesAlg = Aes.Create())
{
using (var encryptor = aesAlg.CreateEncryptor(key, aesAlg.IV))
{
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(text);
}
var iv = aesAlg.IV;
var decryptedContent = msEncrypt.ToArray();
var result = new byte[iv.Length + decryptedContent.Length];
Buffer.BlockCopy(iv, 0, result, 0, iv.Length);
Buffer.BlockCopy(decryptedContent, 0, result, iv.Length, decryptedContent.Length);
return Convert.ToBase64String(result);
}
}
}
}
Method added for Decryption:
public static string DecryptString(string cipherText, string keyString)
{
var fullCipher = Convert.FromBase64String(cipherText);
var iv = new byte[16];
var cipher = new byte[16];
Buffer.BlockCopy(fullCipher, 0, iv, 0, iv.Length);
Buffer.BlockCopy(fullCipher, iv.Length, cipher, 0, iv.Length);
var key = Encoding.UTF8.GetBytes(keyString);
using (var aesAlg = Aes.Create())
{
using (var decryptor = aesAlg.CreateDecryptor(key, iv))
{
string result;
using (var msDecrypt = new MemoryStream(cipher))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
result = srDecrypt.ReadToEnd();
}
}
}
return result;
}
}
}
Here is the Error Snap which occurs in the DecryptString() method:
Any advice, how to solve this issue?
Clue:
var cipher = new byte[16];
Why are you assuming your cipher would be ONLY 16 bytes ? What if it is more than this ?
In fact, if I run this program and debug, I see that your cipher is 32 bytes.
So, the following 2 line changes makes it work:
var cipher = new byte[32];
Buffer.BlockCopy(fullCipher, iv.Length, cipher, 0, cipher.Length);
In any case, you would need to dynamically determine your size of cipher.

AES (rijndael) decryption

I have a Security class that Encode and Decode string, but when I try do decode - something going wrong.
Here is my Security class:
class Security
{
public static String encrypt(String imput, String key)
{
String cipherText;
var rijndael = new RijndaelManaged()
{
Key = Encoding.Unicode.GetBytes(key),
Mode = CipherMode.ECB,
BlockSize = 128,
Padding = PaddingMode.Zeros,
};
ICryptoTransform encryptor = rijndael.CreateEncryptor(rijndael.Key, null);
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
using (var streamWriter = new StreamWriter(cryptoStream))
{
streamWriter.Write(imput);
streamWriter.Flush();
}
cipherText = Convert.ToBase64String(memoryStream.ToArray());
}
}
return cipherText;
}
public static String decrypt(String imput, String key)
{
byte[] data = Convert.FromBase64String(imput);
String decrypted;
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Encoding.UTF8.GetBytes(key);
rijAlg.Mode = CipherMode.ECB;
rijAlg.BlockSize = 128;
rijAlg.Padding = PaddingMode.Zeros;
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, null);
using (MemoryStream msDecrypt = new MemoryStream(data))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
decrypted = srDecrypt.ReadToEnd();
}
}
}
}
return decrypted;
}
}
In program.cs:
String A = Security.encrypt("text", "1234567891234567");
A = Security.decrypt(A, "1234567891234567");
Finaly it return something like that: �%����;\0�\a��f6 , but I need original string. Where I made a mistake?
Use the same encoding in both methods, either Encoding.Unicode or Encoding.UTF8

Categories