需求:
Alice:使用Bob的公匙加密邮件(邮件内容+ Alice用自己的密钥加密的签名)
Bob:使用自己的密匙解密邮件,用Alice公匙解密签名。
代码分析:
代码
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace SecureTransfer
{
class Program
{
private CngKey _aliceKey;
private CngKey _bobKey;
private byte[] _alicePubKeyBlob;
private byte[] _bobPubKeyBlob;
static async Task Main()
{
var p = new Program();
await p.RunAsync();
Console.ReadLine();
}
private async Task RunAsync()
{
try
{
CreateKeys();
byte[] encrytpedData = await AliceSendsDataAsync("this is a secret message for Bob");
await BobReceivesDataAsync(encrytpedData);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void CreateKeys()
{
_aliceKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP521);
_bobKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP521);
_alicePubKeyBlob = _aliceKey.Export(CngKeyBlobFormat.EccPublicBlob);
_bobPubKeyBlob = _bobKey.Export(CngKeyBlobFormat.EccPublicBlob);
}
private async Task<byte[]> AliceSendsDataAsync(string message)
{
Console.WriteLine($"Alice sends message: {message}");
byte[] rawData = Encoding.UTF8.GetBytes(message);
byte[] encryptedData = null;
using (var aliceAlgorithm = new ECDiffieHellmanCng(_aliceKey))
using (CngKey bobPubKey = CngKey.Import(_bobPubKeyBlob,
CngKeyBlobFormat.EccPublicBlob))
{
byte[] symmKey = aliceAlgorithm.DeriveKeyMaterial(bobPubKey);
Console.WriteLine("Alice creates this symmetric key with " +
$"Bobs public key information: { Convert.ToBase64String(symmKey)}");
using (var aes = new AesCryptoServiceProvider())
{
aes.Key = symmKey;
aes.GenerateIV();
using (ICryptoTransform encryptor = aes.CreateEncryptor())
using (var ms = new MemoryStream())
{
// create CryptoStream and encrypt data to send
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
// write initialization vector not encrypted
await ms.WriteAsync(aes.IV, 0, aes.IV.Length);
await cs.WriteAsync(rawData, 0, rawData.Length);
}
encryptedData = ms.ToArray();
}
aes.Clear();
}
}
Console.WriteLine($"Alice: message is encrypted: {Convert.ToBase64String(encryptedData)}"); ;
Console.WriteLine();
return encryptedData;
}
private async Task BobReceivesDataAsync(byte[] encryptedData)
{
Console.WriteLine("Bob receives encrypted data");
byte[] rawData = null;
var aes = new AesCryptoServiceProvider();
int nBytes = aes.BlockSize >> 3;
byte[] iv = new byte[nBytes];
for (int i = 0; i < iv.Length; i++)
iv[i] = encryptedData[i];
using (var bobAlgorithm = new ECDiffieHellmanCng(_bobKey))
using (CngKey alicePubKey = CngKey.Import(_alicePubKeyBlob,
CngKeyBlobFormat.EccPublicBlob))
{
byte[] symmKey = bobAlgorithm.DeriveKeyMaterial(alicePubKey);
Console.WriteLine("Bob creates this symmetric key with " +
$"Alices public key information: {Convert.ToBase64String(symmKey)}");
aes.Key = symmKey;
aes.IV = iv;
using (ICryptoTransform decryptor = aes.CreateDecryptor())
using (MemoryStream ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
{
await cs.WriteAsync(encryptedData, nBytes, encryptedData.Length - nBytes);
}
rawData = ms.ToArray();
Console.WriteLine($"Bob decrypts message to: {Encoding.UTF8.GetString(rawData)}");
}
aes.Clear();
}
}
}
}