Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 39 You must be signed in to star a gist
  • Fork 19 You must be signed in to fork a gist
  • Save Oranzh/2520823f9d1cea603e60b8e8f3fe1d36 to your computer and use it in GitHub Desktop.
Save Oranzh/2520823f9d1cea603e60b8e8f3fe1d36 to your computer and use it in GitHub Desktop.
AES-256 encryption and decryption in PHP and C#

AES-256 encryption and decryption in PHP and C#

Update: There is a more secure version available. Details

PHP

<?php

$plaintext = 'My secret message 1234';
$password = '3sc3RLrpd17';
$method = 'aes-256-cbc';

// Must be exact 32 chars (256 bit)
$password = substr(hash('sha256', $password, true), 0, 32);
echo "Password:" . $password . "\n";

// IV must be exact 16 chars (128 bit)
$iv = chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0);

// av3DYGLkwBsErphcyYp+imUW4QKs19hUnFyyYcXwURU=
$encrypted = base64_encode(openssl_encrypt($plaintext, $method, $password, OPENSSL_RAW_DATA, $iv));

// My secret message 1234
$decrypted = openssl_decrypt(base64_decode($encrypted), $method, $password, OPENSSL_RAW_DATA, $iv);

echo 'plaintext=' . $plaintext . "\n";
echo 'cipher=' . $method . "\n";
echo 'encrypted to: ' . $encrypted . "\n";
echo 'decrypted to: ' . $decrypted . "\n\n";

C#

using System.Security.Cryptography;
using System.IO;
using System.Text;
using System;

public string EncryptString(string plainText, byte[] key, byte[] iv)
{
    // Instantiate a new Aes object to perform string symmetric encryption
    Aes encryptor = Aes.Create();

    encryptor.Mode = CipherMode.CBC;
    //encryptor.KeySize = 256;
    //encryptor.BlockSize = 128;
    //encryptor.Padding = PaddingMode.Zeros;

    // Set key and IV
    encryptor.Key = key;
    encryptor.IV = iv;

    // Instantiate a new MemoryStream object to contain the encrypted bytes
    MemoryStream memoryStream = new MemoryStream();

    // Instantiate a new encryptor from our Aes object
    ICryptoTransform aesEncryptor = encryptor.CreateEncryptor();

    // Instantiate a new CryptoStream object to process the data and write it to the 
    // memory stream
    CryptoStream cryptoStream = new CryptoStream(memoryStream, aesEncryptor, CryptoStreamMode . Write);

    // Convert the plainText string into a byte array
    byte[] plainBytes = Encoding.ASCII.GetBytes(plainText);

    // Encrypt the input plaintext string
    cryptoStream.Write(plainBytes, 0, plainBytes . Length);

    // Complete the encryption process
    cryptoStream.FlushFinalBlock();

    // Convert the encrypted data from a MemoryStream to a byte array
    byte[] cipherBytes = memoryStream.ToArray();

    // Close both the MemoryStream and the CryptoStream
    memoryStream.Close();
    cryptoStream.Close();

    // Convert the encrypted byte array to a base64 encoded string
    string cipherText = Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length);

    // Return the encrypted data as a string
    return cipherText;
}

public string DecryptString(string cipherText, byte[] key, byte[] iv)
{
    // Instantiate a new Aes object to perform string symmetric encryption
    Aes encryptor = Aes.Create();

    encryptor.Mode = CipherMode.CBC;
    //encryptor.KeySize = 256;
    //encryptor.BlockSize = 128;
    //encryptor.Padding = PaddingMode.Zeros;

    // Set key and IV
    encryptor.Key = key;
    encryptor.IV = iv;

    // Instantiate a new MemoryStream object to contain the encrypted bytes
    MemoryStream memoryStream = new MemoryStream();

    // Instantiate a new encryptor from our Aes object
    ICryptoTransform aesDecryptor = encryptor.CreateDecryptor();

    // Instantiate a new CryptoStream object to process the data and write it to the 
    // memory stream
    CryptoStream cryptoStream = new CryptoStream(memoryStream, aesDecryptor, CryptoStreamMode . Write);

    // Will contain decrypted plaintext
    string plainText = String.Empty;

    try {
        // Convert the ciphertext string into a byte array
        byte[] cipherBytes = Convert.FromBase64String(cipherText);

        // Decrypt the input ciphertext string
        cryptoStream.Write(cipherBytes, 0, cipherBytes . Length);

        // Complete the decryption process
        cryptoStream.FlushFinalBlock();

        // Convert the decrypted data from a MemoryStream to a byte array
        byte[] plainBytes = memoryStream.ToArray();

        // Convert the decrypted byte array to string
        plainText = Encoding.ASCII.GetString(plainBytes, 0, plainBytes.Length);
    } finally {
        // Close both the MemoryStream and the CryptoStream
        memoryStream.Close();
        cryptoStream.Close();
    }

    // Return the decrypted data as a string
    return plainText;
}

Usage

string message = "My secret message 1234";
string password = "3sc3RLrpd17";

// Create sha256 hash
SHA256 mySHA256 = SHA256Managed.Create();
byte[] key = mySHA256.ComputeHash(Encoding.ASCII.GetBytes(password));

// Create secret IV
byte[] iv = new byte[16] { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };

string encrypted = this.EncryptString(message, key, iv);
string decrypted = this.DecryptString(encrypted, key, iv);

Console.WriteLine(encrypted);
Console.WriteLine(decrypted);

Source: https://stackoverflow.com/a/45574121/1461181

Version 2

A more secure password should contain a cost factor. Here is the complete example code:

PHP

<?php

$plaintext = 'My secret message 1234';
$password = '3sc3RLrpd17';
$method = 'aes-256-cbc';

$key = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
echo "Key:" . $key . "\n";

// IV must be exact 16 chars (128 bit)
$iv = chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0);

// av3DYGLkwBsErphcyYp+imUW4QKs19hUnFyyYcXwURU=
$encrypted = base64_encode(openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv));

// My secret message 1234
$decrypted = openssl_decrypt(base64_decode($encrypted), $method, $key, OPENSSL_RAW_DATA, $iv);

echo 'plaintext=' . $plaintext . "\n";
echo 'cipher=' . $method . "\n";
echo 'encrypted to: ' . $encrypted . "\n";
echo 'decrypted to: ' . $decrypted . "\n\n";

C#

In C# you have to install the BCrypt-Official package and generate a hash password like this:

using System.Security.Cryptography;
using System.IO;
using System.Text;
using System;

public string EncryptString(string plainText, byte[] key, byte[] iv)
{
    // Instantiate a new Aes object to perform string symmetric encryption
    Aes encryptor = Aes.Create();

    encryptor.Mode = CipherMode.CBC;
    //encryptor.KeySize = 256;
    //encryptor.BlockSize = 128;
    //encryptor.Padding = PaddingMode.Zeros;

    // Set key and IV
    encryptor.Key = key.Take(32).ToArray();
    encryptor.IV = iv;

    // Instantiate a new MemoryStream object to contain the encrypted bytes
    MemoryStream memoryStream = new MemoryStream();

    // Instantiate a new encryptor from our Aes object
    ICryptoTransform aesEncryptor = encryptor.CreateEncryptor();

    // Instantiate a new CryptoStream object to process the data and write it to the 
    // memory stream
    CryptoStream cryptoStream = new CryptoStream(memoryStream, aesEncryptor, CryptoStreamMode.Write);

    // Convert the plainText string into a byte array
    byte[] plainBytes = Encoding.ASCII.GetBytes(plainText);

    // Encrypt the input plaintext string
    cryptoStream.Write(plainBytes, 0, plainBytes.Length);

    // Complete the encryption process
    cryptoStream.FlushFinalBlock();

    // Convert the encrypted data from a MemoryStream to a byte array
    byte[] cipherBytes = memoryStream.ToArray();

    // Close both the MemoryStream and the CryptoStream
    memoryStream.Close();
    cryptoStream.Close();

    // Convert the encrypted byte array to a base64 encoded string
    string cipherText = Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length);

    // Return the encrypted data as a string
    return cipherText;
}

public string DecryptString(string cipherText, byte[] key, byte[] iv)
{
    // Instantiate a new Aes object to perform string symmetric encryption
    Aes encryptor = Aes.Create();

    encryptor.Mode = CipherMode.CBC;
    //encryptor.KeySize = 256;
    //encryptor.BlockSize = 128;
    //encryptor.Padding = PaddingMode.Zeros;

    // Set key and IV
    encryptor.Key = key.Take(32).ToArray();
    encryptor.IV = iv;

    // Instantiate a new MemoryStream object to contain the encrypted bytes
    MemoryStream memoryStream = new MemoryStream();

    // Instantiate a new encryptor from our Aes object
    ICryptoTransform aesDecryptor = encryptor.CreateDecryptor();

    // Instantiate a new CryptoStream object to process the data and write it to the 
    // memory stream
    CryptoStream cryptoStream = new CryptoStream(memoryStream, aesDecryptor, CryptoStreamMode.Write);

    // Will contain decrypted plaintext
    string plainText = String.Empty;

    try
    {
        // Convert the ciphertext string into a byte array
        byte[] cipherBytes = Convert.FromBase64String(cipherText);

        // Decrypt the input ciphertext string
        cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);

        // Complete the decryption process
        cryptoStream.FlushFinalBlock();

        // Convert the decrypted data from a MemoryStream to a byte array
        byte[] plainBytes = memoryStream.ToArray();

        // Convert the decrypted byte array to string
        plainText = Encoding.ASCII.GetString(plainBytes, 0, plainBytes.Length);
    }
    finally
    {
        // Close both the MemoryStream and the CryptoStream
        memoryStream.Close();
        cryptoStream.Close();
    }

    // Return the decrypted data as a string
    return plainText;
}

Usage

string message = "My secret message 1234";
string password = "3sc3RLrpd17";

// hash the password with BCrypt
string hashedPassword = BCrypt.Net.BCrypt.HashPassword(password, 12);

// Convert hashed password to array
byte[] key = Encoding.ASCII.GetBytes(hashedPassword);

// Create secret IV
byte[] iv = new byte[16] { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };

string encrypted = this.EncryptString(message, key, iv);
string decrypted = this.DecryptString(encrypted, key, iv);

Console.WriteLine(encrypted);
Console.WriteLine(decrypted);
@futuresoft3
Copy link

thz it's work

@pdalvi1893
Copy link

Some really helpful piece of code. It resolved my issue.
THANKS A LOT!!!!

@YungSamzy
Copy link

This is one of the best gists on this website. I constantly come back to here looking at how you did this. Wonderful work!

@jpcarpanezi
Copy link

How can i search the version 2, if i store in database, without decrypt every row?

@fatihamalam
Copy link

thanks a lot sir!!! this one is very help me.

@thanhduongdj
Copy link

i want to php ????????????

public static string Decrypt(string cipherText, string passPhrase)
{
var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
System.IO.File.WriteAllText("saltStringBytes.txt", string.Join(", ", saltStringBytes));

using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
{
	var keyBytes = password.GetBytes(Keysize / 8);
	using (var symmetricKey = new RijndaelManaged())
	{
		symmetricKey.BlockSize = 256;
		symmetricKey.Mode = CipherMode.CBC;
		symmetricKey.Padding = PaddingMode.PKCS7;
		using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
		{
			using (var memoryStream = new MemoryStream(cipherTextBytes))
			{
				using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
				{
					var plainTextBytes = new byte[cipherTextBytes.Length];
					var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
					memoryStream.Close();
					cryptoStream.Close();
					return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
				}
			}
		}
	}
}

}

@abusym
Copy link

abusym commented Jun 8, 2021

Thanks a lot!

@ndirituedwin
Copy link

Please can someone help me to implement decryption using php of password encrypted in c#.This problem has been disturbing me for more than two weeks now and any help would be very much appreciated.Here is the c# password encryption method and i need a php decryption function than decrypts password encrypted using c#

public sealed class EncDec
{
public string passPhrase = "ogolla onyango fredrick";

     public string saltValue = "quinter akoth ogolla";

     public string hashAlgorithm = "SHA1";

     public string initVector = "@1B2c3D4e5F6g7H8";

     public int passwordIterations = 2;

     public int keySize = 256;

public string sEncrypt(string plainText)
{
string r = null;
try
{
byte[] initVectorBytes = Encoding.ASCII.GetBytes(this.initVector);
byte[] saltValueBytes = Encoding.ASCII.GetBytes(this.saltValue);
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
PasswordDeriveBytes password = new PasswordDeriveBytes(this.passPhrase, saltValueBytes, this.hashAlgorithm, this.passwordIterations);
byte[] keyBytes = password.GetBytes(this.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, (int)plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] cipherTextBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
r = Convert.ToBase64String(cipherTextBytes);
}
catch (Exception exception)
{
throw;
}
return r;
}

@KibaWolfRain
Copy link

KibaWolfRain commented Nov 19, 2021

Oh my god, you are a genius, I've been searching for hours and looking for a code that works to encrypt and decrypt between PHP and C# but nothing worked until i found your code, thank you very much!

@Indoraptor1
Copy link

Indoraptor1 commented Apr 7, 2022

Can this code be used for encryption in php and decryption that in c #? (I want to encrypt my user details in php, get that code via GET api and decrypt it in the c# client) (I tryed it, but i always got errors)
System.Security.Cryptography.CryptographicException: 'Padding is invalid and cannot be removed.'

@SiriluckTomapa
Copy link

// รบกวนช่วยแปลงข้อมูลตามตารางนี้เพื่อเขียนเป็น Code เข้ารหัสให้หน่อยได้มั้ยค่ะ //
"CID" VARCHAR2(13 BYTE),
"FNAME" VARCHAR2(400 BYTE),
"MOBILE_NO" VARCHAR2(10 BYTE),
"AMOUNT" NUMBER(10,2),
"SMS_FLAG" VARCHAR2(1 BYTE),
"UPD_DATE" TIMESTAMP (6),
"SMS_DATE" TIMESTAMP (6),
"SEQ" NUMBER(10,0)

@yosun
Copy link

yosun commented Nov 16, 2022

Why are you manually setting the IV when AES comes with its own IV generation?

        Aes aes = new AesCryptoServiceProvider();
        aes.GenerateIV();
        byte[] iv = aes.IV;
```

@al2sara
Copy link

al2sara commented Feb 3, 2023

Can this code be used for encryption in php and decryption that in c #? (I want to encrypt my user details in php, get that code via GET api and decrypt it in the c# client) (I tryed it, but i always got errors) System.Security.Cryptography.CryptographicException: 'Padding is invalid and cannot be removed.'

Add these two block in "DecryptString" function after "encryptor.Mode = CipherMode.CBC" code block:

encryptor.KeySize = 256;
encryptor.Padding = PaddingMode.PKCS7;

@alexandr1369
Copy link

Thanks a lot!

@tonzsm
Copy link

tonzsm commented Jul 4, 2023

Can this code be used for encryption in php and decryption that in c #? (I want to encrypt my user details in php, get that code via GET api and decrypt it in the c# client) (I tryed it, but i always got errors) System.Security.Cryptography.CryptographicException: 'Padding is invalid and cannot be removed.'

Add these two block in "DecryptString" function after "encryptor.Mode = CipherMode.CBC" code block:

encryptor.KeySize = 256;
encryptor.Padding = PaddingMode.PKCS7;

i already add but dont work

@KaliMuthuCyg
Copy link

i cant get $IV

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment