Joe*_*Joe 0 c# encryption cryptography aes
因此,我正在尝试实现一种简单的端到端加密方案,在该方案中,客户端与另一客户端进行握手,方法是使用其私钥进行加密,将公钥发送给第二个客户端私钥进行加密,然后再使用私钥解密客户端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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试去做
var decryptedOnce = c.DecryptMessage(encryptedTwice);
Run Code Online (Sandbox Code Playgroud)
我收到“ cryptographicexception填充无效,无法删除”。
首先,AES是对称的分组密码,仅凭其本身不足以实现端到端加密。它可以用作部分的端至端的加密,但需要非对称加密系统(如RSA)的设计的实际“端到endness”。通常,AES仅用作实际数据的密码,而RSA通过一个相互的服务器来促进两个客户端之间的密钥交换。
其次,关于您的代码,您的错误在于假设您可以将随机二进制数据转换为字符串: System.Text.Encoding.Default.GetString(encrypted)
你做不到 由于字符编码的工作原理,将原始数据转换为UTF8(应使用哪种格式而不是ASCII)并再次返回,并不总能返回相同的数据。我建议您改为使用Convert.ToBase64String,它将转换为base64格式,该格式旨在将二进制数据表示为常见的字符串字符,并将在转换之间保持数据。
这里关于填充的错误只是上面所写内容的副作用。请勿删除填充物。
最后,我建议您在继续该项目之前认真阅读密码学主题。我希望您不打算在生产中使用它,但是如果您这样做,那么上面的代码有很多缺陷。不要在生产代码中使用它。