加密失败



我最近将以前的加密程序从Java转换为C#。解密函数运行良好(使用Java加密字符串进行测试),但加密会产生Java程序或C#程序都无法解码的结果。下面包括代码和单元测试,以及输出。GetKey()函数是我自己的salt生成的键,它为给定的输入正确地生成相同的键(在Java和C#中测试)。

加密和解密函数是完全对偶的。我不明白为什么一个有效,另一个无效。

我已经将所有文本减少到base64,以避免java和C#之间的符号陷阱。在解密函数中插入Java加密的字符串(通过调试器),它运行良好。加密字符串在解密和Java版本中都无法解码,错误相同

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Timers;
namespace Krypto
{
class Program
{
static void Main(string[] args)
{
string text;
string key;
string encrypText;
string decryptText;
Console.Write("Plese enter text to encrypt:");
text = Console.ReadLine();
Console.WriteLine("");
Console.Write("Plese enter Key:");
key = Console.ReadLine();
Console.WriteLine("");
encrypText = EncryptString(text, key);
Console.WriteLine("The encrypted string is: "+ encrypText);
decryptText = Decrypt(encrypText, key);
Console.WriteLine("The decrypted string is: " + decryptText);
if (text.Equals(decryptText)) Console.WriteLine("The test was sucessful");
else Console.WriteLine("The test failed!");
Console.ReadKey();
}

static string EncryptString(string text, string key)
{
byte[] key16 = getKey16(key);
string text64 = System.Convert.ToBase64String(System.Text.ASCIIEncoding.UTF8.GetBytes(text));
byte[] encrypted;
byte[] ivArr = { 1, 3, 3, 4, 5, 6, 6, 7, 4, 3, 2, 1, 7, 5, 5, 7 };
byte[] IVBytes16Value = new byte[16];
Array.Copy(ivArr, IVBytes16Value, 16);
// Create an RijndaelManaged object 
// with the specified key and IV. 
using (RijndaelManaged aes = new RijndaelManaged())
{
aes.Key = key16; 
aes.IV = IVBytes16Value;
aes.BlockSize = 128;
aes.KeySize = 256;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7; 

// Create a decryptor to perform the stream transform.
ICryptoTransform encryptor = aes.CreateEncryptor();
try
{
byte[] textBytes = Convert.FromBase64CharArray(text64.ToCharArray(), 0, text64.Length);
encrypted = encryptor.TransformFinalBlock(textBytes, 0, textBytes.Length);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
return "";
};
}

// Return the encrypted bytes from the memory stream. 
return Convert.ToBase64String(encrypted); 
}
private static string Decrypt(string CipherText, string key)
{
byte[] key16 = getKey16(key);
RijndaelManaged aes = new RijndaelManaged();
aes.BlockSize = 128;
aes.KeySize = 256;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
byte[] ivArr = { 1, 3, 3, 4, 5, 6, 6, 7, 4, 3, 2, 1, 7, 5, 5, 7 };
byte[] IVBytes16Value = new byte[16];
Array.Copy(ivArr, IVBytes16Value, 16);
aes.Key = key16;
aes.IV = IVBytes16Value;
ICryptoTransform decrypto = aes.CreateDecryptor();
byte[] decryptedData = null;
try
{
byte[] encryptedBytes = Convert.FromBase64CharArray(CipherText.ToCharArray(), 0, CipherText.Length);
decryptedData = decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
return ""; 
};
return System.Text.ASCIIEncoding.UTF8.GetString(decryptedData);
}
}
private static byte[] getKey16(string key)
{
byte[] key16 = new byte[16];
//make key a 64bit string
string base64key = System.Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(key));
byte[] keyArr = Convert.FromBase64String(base64key);
int keyarraysize = keyArr.Count();
if (keyarraysize < 16)
{
int counter = 0;
while (keyarraysize * (counter + 1) < 16)
{
for (int i = 0; i < keyarraysize; ++i) key16[i + keyarraysize * counter] = keyArr[i];
++counter;
}
for (int i = keyarraysize * counter; i < 16; ++i)
{
key16[i] = 0; 
}
}
else for (int i = 1; i < 16; ++i) key16[i] = keyArr[i];
return key16;
}
}

C#中的加密和解密是完全对偶的。它应该只是产生一个正确的测试,相反,我得到的输出低于

请输入文本进行加密:这是一个测试

Plese输入密钥:testKey

加密字符串为:vLCR4QCJcVHvN4ss7H4Q2g==错误:填充无效,无法删除。解密后的字符串为:测试失败!

如果设置KeySize,则密钥将设置为null(生成随机密钥)。

参见源

事实上,您不需要设置KeySize,因为程序知道如何根据关键字进行计算。

最新更新