【发布时间】:2019-10-03 20:58:54
【问题描述】:
我正在考虑将这个“解密”函数从 C# 移植到 Python(来源: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);
}
}
}
}
}
}
我已经在 C# 中加密了“Hello World”,并设法达到了在 Python 中一直到(包括)keyBytes 的正确值。我尝试使用 pprp (https://pypi.org/project/pprp/) 和其他库来获取解密的文本,但无论我尝试什么,我只会得到“错误的 IV 大小”或垃圾数据。我假设我正在为 PKCS7 填充而苦苦挣扎,但此时我完全迷失了。非常感谢最后一部分的任何帮助。 :)
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))
【问题讨论】:
标签: c# python encryption