我正在尝试解密一个用Java程序加密的文件,据称使用默认IV的AES-256 CBC。
如果我使用常规解密方法(DecryptAesCbc),则只有第一个块被成功解密。
如果我使用Java开发人员建议的解密方法(Decrypt),则所有文本均已成功解密,最后加上了一些附加字符(可能是填充字符)。
工作示例: https://dotnetfiddle.net/M1zQbS
using System;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
/*
Original text:
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
Alleged encryption algorithm: AES CBC 256bit key (default IV) - file was encrypted in Java program.
*/
public class Program
{
//BASE64 encoded cyphertext
public static string encryptedFileBase64 = "k+8W4j0bec7AlcuxQ017lcSuZesp6hroADqN6nsYfMJyvpzrPQEGplGvcWd9Th7buerMkkpXYRGXJm+J4rVdwxi8nMZkithPrweUpHn27I/Td1ETuVJDQCfo/3ZG0/Hya/zvvq+A8YOgreC1qDkg/ap/Wci7RfVdBD1RXzhrLLD6PcdyZW34AWwjvGAnqrR5KLBeGxT6txTjx/V9SR21rD5LLz12QB4g6A6nulLfZiOHKhRydr9XpJzbISjjAh8/RAGDQHtEwdvbWngH/c7zmrZDL1gsC9e7Ia2wLeTQXSQkb6DAeb7XFyjHObX099xeMpjT9ZnELe/W1eCayC881iEoIVsB1mQA8FktOxyPHwDqU0cLMDjpLtu/1BzW838nCZEKExCKeRjeEDDtixU+KLl/BtDCXMGKXQPPaJk8gK9Ytb7+KCE+h4qAatUBydqIu9wtULu6qsk08S7tWhYHdDJiBToyizogNSUgsLQt89ssLYeb2Iof/ybHDXGi8UlgUohSuvzARUffhtYtmm4cljO92XdS+6bPOX7oW4Od3jPldXOnITZyj95lD3pZf2ss3xIan8UZ3MJNyIvnVR/FGqF/lBxyNIcbRWaMXheb+QBKEQsmphSrbR5AMdo7GsTSw32o7wJ1dqBrK0Sl5fsUjtY4ivV88TWqkoSsyT1XczDK8IsOgXFBGp/NxDcBrQV0HyTkN7AchNdVj7b5LRDwBOKag4jGwb87pyFdCjtAEd4XdS7asvMOoEBQNSL/B0NXFqWB5SyFHhHZYK7ewT9P38zsB8zHxYDcfaSujwmaS5YOVw8/ltO3qQfy02zy/3K+";
//BASE64 encoded AES key
public static string aesKeyBase64 = "lAw0kowr1i//T6Bci78bRX/lIRIwwKeGUz4pHDz0jjo=";
public static string encryptedFileBase64_2 = "0S0tQ2jupE7bHbVspWCOOSWs/hEm/da+oFSVEU1XkzenZmb+OXWM7+4WUNAUU2hZ4IWJULl34Ha8pIb2btLOuv+KSOmFG5wX+rRMd2y66/HLDcHgOkZUPG3c+MV6261q3U2cFad6kZzRx1td3eXiD2vNljP1VKT1Fcr2c8sVVH2Fo1tQEm21YAjxgvcl3k6r6B0zigL1iAYH5liC65LQLihUyrcPLZ7vy2Wt2tKeFUE/kVXwX9/KHQEsY+j9HCE8zPEGkjieimxY8uaxKvEZBVYZ1EAT92YIpOAaVOX8q61uQOurXqJFJ2COLD3MXH0/Cnp3aSQll/l2LmfiS396JbHw6NYn7GC+2eGiMbXeQs0Wo7b17hkQeSLtsB8U+Wdx";
public static string aesKeyBase64_2 = "TL9wAPaCWj53zdbAVDdrtpAUtlKxDtySI4QtKQ5KstA=";
public static void Main()
{
byte[] key = Convert.FromBase64String(aesKeyBase64);
//IV
byte[] iv = new byte[16] { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
Console.WriteLine("------------------First file-----------------\n\n");
string decrypted = AesUtils.Decrypt(Convert.FromBase64String(encryptedFileBase64), key, iv);
Console.WriteLine("------------------Proposed decryption process-----------------");
Console.WriteLine(decrypted);
Console.WriteLine("\n---------------AES CBC decryption process--------------------");
string decrypted2 = AesUtils.DecryptAesCbc(Convert.FromBase64String(encryptedFileBase64), key, iv);
Console.WriteLine(decrypted2);
Console.WriteLine("\n\n------------------Second file-----------------\n\n");
key = Convert.FromBase64String(aesKeyBase64_2);
decrypted = AesUtils.Decrypt(Convert.FromBase64String(encryptedFileBase64_2), key, iv);
Console.WriteLine("------------------Proposed decryption process-----------------");
Console.WriteLine(decrypted);
Console.WriteLine("\n---------------AES CBC decryption process--------------------");
decrypted2 = AesUtils.DecryptAesCbc(Convert.FromBase64String(encryptedFileBase64_2), key, iv);
Console.WriteLine(decrypted2);
}
}
public static class AesUtils
{
public static string Decrypt(byte[] cipherBytes, byte[] key, byte[] iv)
{
using (Aes encryptor = GetCryptoAlgorithm())
{
encryptor.Key = key;
encryptor.IV = iv;
using (MemoryStream memoryStream = new MemoryStream(cipherBytes.Length))
{
string plainText = String.Empty;
for (int i = 0; i < cipherBytes.Length; i = i + 16)
{
encryptor.IV = iv;
ICryptoTransform aesDecryptor = encryptor.CreateDecryptor();
CryptoStream cryptoStream = new CryptoStream(memoryStream, aesDecryptor, CryptoStreamMode.Write);
cryptoStream.Write(cipherBytes, i, 16);
cryptoStream.FlushFinalBlock();
}
byte[] plainBytes2 = memoryStream.ToArray();
plainText = Encoding.UTF8.GetString(plainBytes2, 0, plainBytes2.Length);
return plainText;
}
}
}
public static string DecryptAesCbc(byte[] inputArray, byte[] key, byte[] iv)
{
using (Aes aes = GetCryptoAlgorithm())
{
aes.Key = key;
aes.IV = iv;
ICryptoTransform cTransform = aes.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
aes.Clear();
return Encoding.UTF8.GetString(resultArray);
}
}
private static Aes GetCryptoAlgorithm()
{
Aes algorithm = Aes.Create();
algorithm.Padding = PaddingMode.None;
algorithm.Mode = CipherMode.CBC;
algorithm.KeySize = 256;
algorithm.BlockSize = 128;
return algorithm;
}
}
答案 0 :(得分:1)
在 ECB 模式下使用PKCS7-padding进行AES加密。
如果使用此配置,它将decrypt correctly并删除填充:
private static Aes GetCryptoAlgorithm()
{
Aes algorithm = Aes.Create();
algorithm.Padding = PaddingMode.PKCS7;
algorithm.Mode = CipherMode.ECB;
algorithm.KeySize = 256;
algorithm.BlockSize = 128;
return algorithm;
}