【发布时间】:2020-02-03 22:12:09
【问题描述】:
我需要两个程序与另一个程序通信,通信应该用 aes 加密,我需要用 diffie hellman 密钥交换来做。我有 DiffieHellman 类来生成密钥,并使用加密、解密方法和两个名为 alice 和 bob 的控制台应用程序,当我运行应用程序时会抛出许多异常。这是我第一次使用密码学和套接字,所以我不明白它们是如何工作的,有人能告诉我我做错了什么,我该如何解决?
public class DiffieHellman
{
private Aes aes = null;
private ECDiffieHellmanCng diffieHellman = null;
private readonly byte[] publicKey;
public DiffieHellman()
{
this.aes = new AesCryptoServiceProvider();
this.diffieHellman = new ECDiffieHellmanCng
{
KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash,
HashAlgorithm = CngAlgorithm.Sha256
};
// This is the public key we will send to the other party
this.publicKey = this.diffieHellman.PublicKey.ToByteArray();
}
public byte[] PublicKey
{
get
{
return this.publicKey;
}
}
public byte[] IV
{
get
{
return this.aes.IV;
}
}
public byte[] Encrypt(byte[] publicKey, string secretMessage)
{
byte[] encryptedMessage;
var key = CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob);
var derivedKey = this.diffieHellman.DeriveKeyMaterial(key); // "Common secret"
this.aes.Key = derivedKey;
using (var cipherText = new MemoryStream())
{
using (var encryptor = this.aes.CreateEncryptor())
{
using (var cryptoStream = new CryptoStream(cipherText, encryptor, CryptoStreamMode.Write))
{
byte[] ciphertextMessage = Encoding.UTF8.GetBytes(secretMessage);
cryptoStream.Write(ciphertextMessage, 0, ciphertextMessage.Length);
}
}
encryptedMessage = cipherText.ToArray();
}
return encryptedMessage;
}
public string Decrypt(byte[] publicKey, byte[] encryptedMessage, byte[] iv)
{
string decryptedMessage;
var key = CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob);
var derivedKey = this.diffieHellman.DeriveKeyMaterial(key);
this.aes.Key = derivedKey;
this.aes.IV = iv;
using (var plainText = new MemoryStream())
{
using (var decryptor = this.aes.CreateDecryptor())
{
using (var cryptoStream = new CryptoStream(plainText, decryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(encryptedMessage, 0, encryptedMessage.Length);
}
}
decryptedMessage = Encoding.UTF8.GetString(plainText.ToArray());
}
return decryptedMessage;
}
}
class Alice
{
static void Main(string[] args)
{
DiffieHellman dhke = new DiffieHellman();
while (true)
{
TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 13000);
server.Start();
Socket s = server.AcceptSocket();
byte[] encryptedText = new byte[1024];
int k = s.Receive(encryptedText);
Console.Write("Friend: ");
byte[] bobPublicKey = new byte[1024];
s.Receive(bobPublicKey);
Console.WriteLine(dhke.Decrypt(bobPublicKey,encryptedText,dhke.IV));
Console.WriteLine();
ASCIIEncoding asen = new ASCIIEncoding();
string message = Console.ReadLine();
s.Send(dhke.Encrypt(dhke.PublicKey,message));
s.Close();
server.Stop();
}
}
}
class Bob
{
static void Main(string[] args)
{
DiffieHellman dhke = new DiffieHellman();
while (true)
{
TcpClient tcpClient = new TcpClient();
tcpClient.Connect("127.0.0.1", 13000);
String message = Console.ReadLine();
Stream clientStream = tcpClient.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] messageBuffer = new byte[1024];
messageBuffer = dhke.Encrypt(dhke.PublicKey, message);
clientStream.Write(messageBuffer, 0, messageBuffer.Length);
clientStream.Write(dhke.PublicKey, 0, dhke.PublicKey.Length);
byte[] encryptedText = new byte[1024];
int k = clientStream.Read(encryptedText, 0, encryptedText.Length);
Console.Write("Friend: ");
byte[] alicePublicKey = new byte[1024];
clientStream.Read(alicePublicKey, 0, alicePublicKey.Length);
Console.WriteLine(dhke.Decrypt(alicePublicKey,encryptedText,dhke.IV));
Console.WriteLine();
tcpClient.Close();
}
}
}
【问题讨论】:
-
您是否考虑过使用 SSLStream 并设置密码?
-
@RowanSmith 这是我大学的作业,我必须使用 diffie hellman 作为密钥和任何对称算法进行加密和解密
-
你遇到了什么异常?它们对你意味着什么?您已经尝试过哪些更改,但无法开始工作?
-
@bartonjs 我发布了一个我修复到现在的答案,我没有任何异常只是一个逻辑问题
标签: c# sockets aes diffie-hellman