客户机/服务器与Diffie-Hellman密钥交换通信,Aes与C#
我需要两个程序与另一个进行通信,通信应该用aes加密,我需要用diffie-hellman密钥交换进行加密。我使用DiffieHellman类生成密钥,使用encrypt、decrypt方法和两个名为alice和bob的控制台应用程序,当我运行这些应用程序时,会抛出许多异常。这是我第一次使用密码和套接字,所以我不明白它们是如何工作的,有人能告诉我我做错了什么,我如何修复它吗客户机/服务器与Diffie-Hellman密钥交换通信,Aes与C#,c#,sockets,aes,diffie-hellman,C#,Sockets,Aes,Diffie Hellman,我需要两个程序与另一个进行通信,通信应该用aes加密,我需要用diffie-hellman密钥交换进行加密。我使用DiffieHellman类生成密钥,使用encrypt、decrypt方法和两个名为alice和bob的控制台应用程序,当我运行这些应用程序时,会抛出许多异常。这是我第一次使用密码和套接字,所以我不明白它们是如何工作的,有人能告诉我我做错了什么,我如何修复它吗 public class DiffieHellman { private Aes aes = null;
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();
}
}
}
到目前为止,我修复了很多问题,diffie-hellman密钥交换很好,使用aes加密/解密,我仍然有一个错误,当我发送文本并在另一个程序中解密时,它会显示一些其他加密字符和解密文本。IV长度为16字节,我将消息长度设置为32字节,当我发送小于或等于16个字符的文本时,它会出错,当我发送大于16个字符的文本时,它会正常工作。
你考虑过使用SSL流并设置密码吗?@RowTransmish这是我大学的一项作业,我必须使用diffie hellman作为密钥,使用任何对称算法进行加密和解密。你有什么例外?它们对你意味着什么?你已经试着改变了什么,但无法开始工作?@bartonjs我发布了一个答案,直到现在我已经解决了这个问题,我没有任何例外,只是一个逻辑问题
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;
this.aes.Padding = PaddingMode.Zeros;
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;
this.aes.Padding = PaddingMode.Zeros;
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)
{
while (true)
{
DiffieHellman dhke = new DiffieHellman();
ASCIIEncoding asen = new ASCIIEncoding();
TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 13000);
server.Start();
Socket s = server.AcceptSocket();
byte[] bobPublicKey = new byte[140];
byte[] bobIV = new byte[16];
s.Send(dhke.PublicKey);
s.Receive(bobPublicKey);
s.Receive(bobIV);
byte[] acceptedMessage = new byte[32];
s.Receive(acceptedMessage);
System.Threading.Thread.Sleep(1000);
Console.WriteLine("Mesazhi qe vjen i enkriptuar " + asen.GetString(acceptedMessage));
Console.WriteLine();
string decryptedMessage = dhke.Decrypt(bobPublicKey, acceptedMessage, bobIV);
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("Friend: ");
Console.WriteLine(decryptedMessage);
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Red;
string mesazhi = Console.ReadLine();
byte[] encryptedMessage = dhke.Encrypt(bobPublicKey, mesazhi);
Console.ResetColor();
Console.WriteLine();
Console.WriteLine("Mesazhi qe dergohet i enkriptuar " + asen.GetString(encryptedMessage));
Console.WriteLine();
s.Send(encryptedMessage);
s.Send(dhke.IV);
s.Close();
server.Stop();
}
}
}
class Bob
{
static void Main(string[] args)
{
while (true)
{
DiffieHellman dhke = new DiffieHellman();
ASCIIEncoding asen = new ASCIIEncoding();
TcpClient tcpClient = new TcpClient();
tcpClient.Connect("127.0.0.1", 13000);
Stream stream = tcpClient.GetStream();
byte[] alicePublicKey = new byte[140];
stream.Read(alicePublicKey, 0, alicePublicKey.Length);
stream.Write(dhke.PublicKey, 0, dhke.PublicKey.Length);
stream.Write(dhke.IV, 0, dhke.IV.Length);
Console.ForegroundColor = ConsoleColor.Red;
String message = Console.ReadLine(); //Shkruaj mesazhin
byte[] encryptedMessage = dhke.Encrypt(alicePublicKey, message);
Console.ResetColor();
Console.WriteLine();
Console.WriteLine("Mesazhi qe dergohet i enkriptuar " + asen.GetString(encryptedMessage));
Console.WriteLine();
stream.Write(encryptedMessage, 0, encryptedMessage.Length);
byte[] acceptedMessage = new byte[32];
byte[] aliceIV = new byte[16];
stream.Read(acceptedMessage, 0, acceptedMessage.Length);
stream.Read(aliceIV, 0, aliceIV.Length);
Console.WriteLine("Mesazhi qe vjen i enkriptuar " + asen.GetString(acceptedMessage));
Console.WriteLine();
string decryptedMessage = dhke.Decrypt(alicePublicKey, acceptedMessage, aliceIV);
Console.ForegroundColor = ConsoleColor.Green;
System.Threading.Thread.Sleep(1000);
Console.Write("Friend: ");
Console.WriteLine(decryptedMessage);
Console.WriteLine();
tcpClient.Close();
}
}
}