Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bluetechy/7a4033d0d787471f00e8266f58f7ee84 to your computer and use it in GitHub Desktop.
Save bluetechy/7a4033d0d787471f00e8266f58f7ee84 to your computer and use it in GitHub Desktop.
Matching Encrypt/Decrypt Methods With Rijndael-128, CBC Mode, PKCS7 Padding in C#.NET, PHP, And Python
DO NOT use these as-is for anything important!
These are only very basic examples and they are missing much of what would be needed for a real-world use case.
These are snippets for matching encrypt and decrypt (Rijndael-128 in CBC mode with PKCS7 padding) in C#.NET, PHP, and Python.
I cobbled these together from various existing examples because at the time it seemed like a lot of existing examples out there for different languages/platforms did not quite match and would require quite a bit more work before they would encrypt/decrypt identically.
Each of these take Keys and IVs that are 16 character strings encoded in base64.
public class Rijndael128Encryptor
{
/*
* Encrypt method
* Both Keys and IVs need to be 16 characters encoded in base64.
*/
public String AES_encrypt(String Input, String AES_Key, String AES_IV)
{
// Create encryptor
var aes = new RijndaelManaged();
aes.KeySize = 128;
aes.BlockSize = 128;
aes.Padding = PaddingMode.PKCS7;
aes.Key = Convert.FromBase64String(AES_Key);
aes.IV = Convert.FromBase64String(AES_IV);
var encrypt = aes.CreateEncryptor(aes.Key, aes.IV);
// Encrypt Input
byte[] xBuff = null;
using (var ms = new MemoryStream())
{
// Convert from UTF-8 String to byte array, write to memory stream and encrypt, then convert to byte array
using (var cs = new CryptoStream(ms, encrypt, CryptoStreamMode.Write))
{
byte[] xXml = Encoding.UTF8.GetBytes(Input);
cs.Write(xXml, 0, xXml.Length);
}
xBuff = ms.ToArray();
}
// Convert from byte array to base64 string then return
String Output = Convert.ToBase64String(xBuff);
return Output;
}
/*
* Decrypt method
* Both Keys and IVs need to be 16 characters encoded in base64.
*/
public String AES_decrypt(String Input, String AES_Key, String AES_IV)
{
// Create decryptor
RijndaelManaged aes = new RijndaelManaged();
aes.KeySize = 128;
aes.BlockSize = 128;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.Key = Convert.FromBase64String(AES_Key);
aes.IV = Convert.FromBase64String(AES_IV);
var decrypt = aes.CreateDecryptor();
// Decrypt Input
byte[] xBuff = null;
using (var ms = new MemoryStream())
{
// Convert from base64 string to byte array, write to memory stream and decrypt, then convert to byte array.
using (var cs = new CryptoStream(ms, decrypt, CryptoStreamMode.Write))
{
byte[] xXml = Convert.FromBase64String(Input);
cs.Write(xXml, 0, xXml.Length);
}
xBuff = ms.ToArray();
}
// Convert from byte array to UTF-8 string then return
String Output = Encoding.UTF8.GetString(xBuff);
return Output;
}
}
<?php
class Rijndael128Encryptor{
/*
* Adds PKCS7 padding
*/
private function addpadding($inputstring)
{
$blocksize = 16;
$len = strlen($inputstring);
$pad = $blocksize - ($len % $blocksize);
$inputstring .= str_repeat(chr($pad), $pad);
return $inputstring;
}
/*
* Strips PKCS7 padding
*/
private function strippadding($inputstring)
{
$slast = ord(substr($inputstring, -1));
$slastc = chr($slast);
if(preg_match("/$slastc{".$slast."}/", $inputstring)){
$inputstring = substr($inputstring, 0, strlen($inputstring)-$slast);
return $inputstring;
} else {
return false;
}
}
/*
* Encrypt method
* Both Keys and IVs need to be 16 characters encoded in base64.
*/
public function encrypt($inputstring, $inputkey, $inputiv)
{
$key = base64_decode($inputkey);
$iv = base64_decode($inputiv);
// Pad text and encrypt
$padded_string = $this->addpadding($inputstring);
$encrypted_string = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $padded_string, MCRYPT_MODE_CBC, $iv);
// Encode to base64 and return
return base64_encode($encrypted_string);
}
/*
* Decrypt method
* Both Keys and IVs need to be 16 characters encoded in base64.
*/
public function decrypt($inputstring, $inputkey, $inputiv)
{
$key = base64_decode($inputkey);
$iv = base64_decode($inputiv);
// Decode from base64 and decrypt
$decoded_string = base64_decode($inputstring);
$decrypted_string = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $decoded_string, MCRYPT_MODE_CBC, $iv);
// Unpad text and return
return $this->strippadding($decrypted_string);
}
}
?>
from Crypto.Cipher import AES
import base64
class RijndaelEncryptor(object):
"""
Encrypts text using Rijndael 128 in CBC mode and using PKCS7 padding
"""
def __init__(self, k=16):
self.k = k #sets block size of 16 for padding, NOT FOR CIPHER
def _pkcs7decode(self, text):
"""
Remove PKCS7 padding from text
"""
val = text[-1]
if val > self.k:
raise ValueError('Input is not padded or padding is corrupt')
l = len(text) - val
return (text[:l]).decode(encoding="UTF-8")
def _pkcs7encode(self, text):
"""
Add PKCS7 padding to text
"""
l = len(text)
val = self.k - (l % self.k)
return text + bytearray([val] * val).decode(encoding="UTF-8")
def encrypt(self, text, input_key, input_iv):
"""
Encrypt method
Both Keys and IVs need to be 16 characters encoded in base64.
"""
# Create aes object
key = base64.b64decode(input_key)
iv = base64.b64decode(input_iv)
aes = AES.new(key, AES.MODE_CBC, iv)
# Pad text and encrypt
pad_text = self._pkcs7encode(text)
cipher_text = aes.encrypt(pad_text)
# Encode to base64 and return
return base64.b64encode(cipher_text)
def decrypt(self, text, input_key, input_iv):
"""
Decrypt method
Both Keys and IVs need to be 16 characters encoded in base64.
"""
# Create aes object
key = base64.b64decode(input_key)
iv = base64.b64decode(input_iv)
aes = AES.new(key, AES.MODE_CBC, iv)
# Decode from base64 and decrypt
decode_text = base64.b64decode(text)
pad_text = aes.decrypt(decode_text)
# Unpad text and return
return self._pkcs7decode(pad_text)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment