所以我试图实现一个简单的端到端加密方案,其中客户端通过使用其私钥加密与另一个客户端进行握手,发送公钥以通过第二个客户端私钥加密,用客户端1的私钥解密并发回,因此客户端2具有公钥。我使用的是C#.Net提供的Aes类,但似乎无法使其正常工作。
我得到的错误是参考填充,我已经看到你可以完全删除填充但是我被告知这不是一个好主意。有谁能解释为什么?另外,我如何知道将解密/加密设置为什么填充以便能够查看有效密钥。
这是我拥有的
class Program
{
static void Main(string[] args)
{
Connection c = new Connection();
Connection d = new Connection();
var encrypted = c.EncryptMessage("stackoverflow");
var decrypted = c.DecryptMessage(encrypted);
var encryptedTwice = d.EncryptMessage(System.Text.Encoding.Default.GetString(encrypted));
var decryptedOnce = c.DecryptMessage(encryptedTwice);
var decryptedTwice = d.DecryptMessage(Encoding.ASCII.GetBytes(decryptedOnce));
Console.WriteLine("Encrypted: " + System.Text.Encoding.Default.GetString(encrypted));
Console.WriteLine("Decrypted: " + decrypted);
Console.WriteLine("Decrypted twice: " + decryptedTwice);
Console.ReadKey();
}
}
class Connection
{
private Aes _encryption;
Connection()
{
_encryption = Aes.Create();
}
public byte[] EncryptMessage(string message)
{
byte[] encrypted;
ICryptoTransform encryptor = _encryption.CreateEncryptor(_encryption.Key, _encryption.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(message);
}
encrypted = msEncrypt.ToArray();
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
}
public string DecryptMessage(byte[] message)
{
string decrypted = "";
ICryptoTransform decryptor = _encryption.CreateDecryptor(_encryption.Key, _encryption.IV);
using (MemoryStream msDecrypt = new MemoryStream(message))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
decrypted = srDecrypt.ReadToEnd();
}
}
return decrypted;
}
}
}
当我尝试
时var decryptedOnce = c.DecryptMessage(encryptedTwice);
我收到" cryptographicexception填充无效,无法删除"。
答案 0 :(得分:4)
首先,AES是一种对称分组密码,它本身并不足以实现端到端加密。它可以用作端到端加密的部分,但需要像RSA这样的非对称加密系统,用于实际的端到端加密#34;的设计。通常,AES仅用作实际数据的密码,其中RSA通过共同服务器促进两个客户端之间的密钥交换。
其次,关于您的代码,您的错误是假设您可以将随机二进制数据转换为字符串:System.Text.Encoding.Default.GetString(encrypted)
你不能这样做。将原始数据转换为UTF8(您应该使用的而不是ASCII)并再次返回将不会总是为您提供相同的数据,因为字符编码的工作方式。我建议你使用Convert.ToBase64String
,它转换为base64格式,用于将二进制数据表示为常见的字符串字符,并将在转换之间维护数据。
关于填充的错误只是上面所写内容的副作用。不要移除衬垫。
最后,我建议您在继续此项目之前先仔细阅读加密主题。我希望你不打算在制作中使用它,但如果你这样做,你上面的代码有很多缺陷。不要在生产代码中使用它。