I'm looking into porting this "Decryption" function from C# to Python (Source: https://stackoverflow.com/a/10177020)
public static string Decrypt(string cipherText, string passPhrase)
{
// Get the complete stream of bytes that represent:
// [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
// Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
// Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
// Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
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);
}
}
}
}
}
}
I have encrypted "Hello World" in C# and managed to get to the point where I have the correct values all the way to (and including) keyBytes in Python. I have tried to get the decrypted text using pprp (https://pypi.org/project/pprp/) and other libraries, but no matter what I try I only get "Wrong IV size" or junk data. I assume that I'm struggling with the PKCS7 padding, but at this point I'm just completely lost. Would highly appreciate any help on the last part. :)
import pprp
import base64
from pkcs7 import PKCS7Encoder
cipherText = "JKjzaiOSreH+l0GSzsatS8nmohRisvINOwrEjHOwIqIXo88CQT0/al7V7vXOmuamfTeJ235O1SZ0Yd2BZk2e2V4MznT7hyzqzu5J326JIReXPeH6EdtPFrxhdTPsfb8Q"
passphrase = "a78356254f093b00e45434828110c7b5"
# This constant is used to determine the keysize of the encryption algorithm in bits.
# We divide this by 8 within the code below to get the equivalent number of bytes.
keysize = 256
# This constant determines the number of iterations for the password bytes generation function.
derivationIterations = 1000
# Get the complete stream of bytes that represent:
# [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
cipherTextBytesWithSaltAndIv = base64.b64decode(cipherText)
cipherTextBytesWithSaltAndIv=list(bytearray(cipherTextBytesWithSaltAndIv))
# Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
saltStringBytes = cipherTextBytesWithSaltAndIv[:int(keysize / 8)]
# Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
ivStringBytes = cipherTextBytesWithSaltAndIv[int(keysize / 8):int((keysize / 8) * 2)]
# Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
cipherTextBytes = cipherTextBytesWithSaltAndIv[int((keysize / 8) * 2):]
keyBytes = pprp.pbkdf2(passphrase.encode('utf-8'), bytes(saltStringBytes), int(keysize / 8))
print(base64.b64encode(keyBytes))