Forked from jeruyyap/Matching Rijndael-128 in C#.NET, PHP, and Python
Created
August 16, 2018 06:34
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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); | |
} | |
} | |
?> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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