对称加密与非对称加密

（一）对称加密（Symmetric Cryptography）

2000年10月2日，美国国家标准与技术研究所（NIST--American National Institute of Standards and Technology）选择了Rijndael算法作为新的高级加密标准（AES--Advanced Encryption Standard）。.NET中包含了Rijndael算法，类名叫RijndaelManaged，下面举个例子。

        private string myData = "hello";
private byte[] cipherText;
private byte[] salt = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0 };

private void mnuSymmetricEncryption_Click(object sender, RoutedEventArgs e)
{
var key = new Rfc2898DeriveBytes(myPassword, salt);
// Encrypt the data.
var algorithm = new RijndaelManaged();
algorithm.Key = key.GetBytes(16);
algorithm.IV = key.GetBytes(16);
var sourceBytes = new System.Text.UnicodeEncoding().GetBytes(myData);
using (var sourceStream = new MemoryStream(sourceBytes))
using (var destinationStream = new MemoryStream())
using (var crypto = new CryptoStream(sourceStream, algorithm.CreateEncryptor(), CryptoStreamMode.Read))
{
moveBytes(crypto, destinationStream);
cipherText = destinationStream.ToArray();
}
MessageBox.Show(String.Format("Data:{0}{1}Encrypted and Encoded:{2}", myData, Environment.NewLine, Convert.ToBase64String(cipherText)));
}
private void moveBytes(Stream source, Stream dest)
{
byte[] bytes = new byte[2048];
var count = source.Read(bytes, 0, bytes.Length);
while (0 != count)
{
dest.Write(bytes, 0, count);
}
}

        private void mnuSymmetricDecryption_Click(object sender, RoutedEventArgs e)
{
if (cipherText == null)
{
MessageBox.Show("Encrypt Data First!");
return;
}
var key = new Rfc2898DeriveBytes(myPassword, salt);
// Try to decrypt, thus showing it can be round-tripped.
var algorithm = new RijndaelManaged();
algorithm.Key = key.GetBytes(16);
algorithm.IV = key.GetBytes(16);
using (var sourceStream = new MemoryStream(cipherText))
using (var destinationStream = new MemoryStream())
using (var crypto = new CryptoStream(sourceStream, algorithm.CreateDecryptor(), CryptoStreamMode.Read))
{
moveBytes(crypto, destinationStream);
var decryptedBytes = destinationStream.ToArray();
var decryptedMessage = new UnicodeEncoding().GetString(
decryptedBytes);
MessageBox.Show(decryptedMessage);
}
}

（二）非对称加密（Asymmetric Cryptography）

        private byte[] rsaCipherText;
private void mnuAsymmetricEncryption_Click(object sender, RoutedEventArgs e)
{
var rsa = 1;
// Encrypt the data.
var cspParms = new CspParameters(rsa);
cspParms.Flags = CspProviderFlags.UseMachineKeyStore;
cspParms.KeyContainerName = "My Keys";
var algorithm = new RSACryptoServiceProvider(cspParms);
var sourceBytes = new UnicodeEncoding().GetBytes(myData);
rsaCipherText = algorithm.Encrypt(sourceBytes, true);
MessageBox.Show(String.Format("Data: {0}{1}Encrypted and Encoded: {2}",
myData, Environment.NewLine,
Convert.ToBase64String(rsaCipherText)));
}

        private void mnuAsymmetricDecryption_Click(object sender, RoutedEventArgs e)
{
if(rsaCipherText==null)
{
MessageBox.Show("Encrypt First!");
return;
}
var rsa = 1;
// decrypt the data.
var cspParms = new CspParameters(rsa);
cspParms.Flags = CspProviderFlags.UseMachineKeyStore;
cspParms.KeyContainerName = "My Keys";
var algorithm = new RSACryptoServiceProvider(cspParms);
var unencrypted = algorithm.Decrypt(rsaCipherText, true);
MessageBox.Show(new UnicodeEncoding().GetString(unencrypted));
}

（1） Alice需要在银行的网站做一笔交易，她的浏览器首先生成了一个随机数作为对称密钥。

（2） Alice的浏览器向银行的网站请求公钥。

（3） 银行将公钥发送给Alice。

（4） Alice的浏览器使用银行的公钥将自己的对称密钥加密。

（5） Alice的浏览器将加密后的对称密钥发送给银行。

（6） 银行使用私钥解密得到Alice浏览器的对称密钥。

（7） Alice与银行可以使用对称密钥来对沟通的内容进行加密与解密了。

（三）总结

（1） 对称加密加密与解密使用的是同样的密钥，所以速度快，但由于需要将密钥在网络传输，所以安全性不高。

（2） 非对称加密使用了一对密钥，公钥与私钥，所以安全性高，但加密与解密速度慢。

（3） 解决的办法是将对称加密的密钥使用非对称加密的公钥进行加密，然后发送出去，接收方使用私钥进行解密得到对称加密的密钥，然后双方可以使用对称加密来进行沟通。

posted @ 2022-04-14 12:00  aspirant  阅读(128)  评论(0编辑  收藏  举报