如何使用AES进行端到端加密

时间:2017-06-23 23:49:07

标签: 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;
        }
    }
}

当我尝试

var decryptedOnce = c.DecryptMessage(encryptedTwice);

我收到" cryptographicexception填充无效,无法删除"。

1 个答案:

答案 0 :(得分:4)

首先,AES是一种对称分组密码,它本身并不足以实现端到端加密。它可以用作端到端加密的部分,但需要像RSA这样的非对称加密系统,用于实际的端到端加密#34;的设计。通常,AES仅用作实际数据的密码,其中RSA通过共同服务器促进两个客户端之间的密钥交换。

其次,关于您的代码,您的错误是假设您可以将随机二进制数据转换为字符串:System.Text.Encoding.Default.GetString(encrypted)

你不能这样做。将原始数据转换为UTF8(您应该使用的而不是ASCII)并再次返回将不会总是为您提供相同的数据,因为字符编码的工作方式。我建议你使用Convert.ToBase64String,它转换为base64格式,用于将二进制数据表示为常见的字符串字符,并将在转换之间维护数据。

关于填充的错误只是上面所写内容的副作用。不要移除衬垫。

最后,我建议您在继续此项目之前先仔细阅读加密主题。我希望你不打算在制作中使用它,但如果你这样做,你上面的代码有很多缺陷。不要在生产代码中使用它。