gpt4 book ai didi

c# - 以安全的方式在服务器和客户端之间交换对称 key

转载 作者:太空宇宙 更新时间:2023-11-03 19:27:28 25 4
gpt4 key购买 nike

我有一个我认为是安全的算法。所以服务器为每个新连接创建一个公钥和私钥组合。在这个例子中,我只处理一个线程,但实际上我必须构建多个线程,以便服务器可以监听多个连接。

客户端是 Alice,它还创建了公钥和私钥组合。这是客户端 Alice 如何创建随机对称 key 以安全地提供给服务器 bob。

服务器代码(鲍勃):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Security.Cryptography;
using System.IO;


namespace ServerListener
{
class Program
{
static TcpListener server;

static CngKey bobKey; // server private key
static byte[] alicePubKeyBlob; // client public key
static byte[] bobPubKeyBlob; // server public key

static byte[] symetricKey; // the symetric key that will later be used to transfer data more efficeintly

static void Main(string[] args)
{

// create server private and public keys
CreateKeys();

// start listening for new connections
IPAddress ipAddress = IPAddress.Parse("192.168.0.120");
server = new TcpListener(ipAddress, 54540);
server.Start();
var client = server.AcceptTcpClient();

// once a connection is established open the stream
var stream = client.GetStream();

// we need the client public key so we need to instantiate it.
alicePubKeyBlob = new byte[bobPubKeyBlob.Length];

// waint until the client send us his public key
stream.Read(alicePubKeyBlob, 0, alicePubKeyBlob.Length);

// alicePubKeyBlob should now be the client's public key

// now let's send this servers public key to the client
stream.Write(bobPubKeyBlob, 0, bobPubKeyBlob.Length);

// encrytpedData will be the data that server will recive encrypted from the client with the server's public key
byte[] encrytpedData = new byte[1024];
// wait until client sends that data
stream.Read(encrytpedData, 0, encrytpedData.Length);

// decrypt the symetric key with the private key of the server
symetricKey = BobReceivesData(encrytpedData);

// server and client should know have the same symetric key in order to send data more efficently and securely
Console.Read();

}

private static void CreateKeys()
{
//aliceKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
bobKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
//alicePubKeyBlob = aliceKey.Export(CngKeyBlobFormat.EccPublicBlob);
bobPubKeyBlob = bobKey.Export(CngKeyBlobFormat.EccPublicBlob);
}

private static byte[] BobReceivesData(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: {0}",
Convert.ToBase64String(symmKey));

aes.Key = symmKey;
aes.IV = iv;

using (ICryptoTransform decryptor = aes.CreateDecryptor())
using (MemoryStream ms = new MemoryStream())
{
var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write);
cs.Write(encryptedData, nBytes, encryptedData.Length - nBytes);
cs.Close();

rawData = ms.ToArray();

Console.WriteLine("Bob decrypts message to: {0}",
Encoding.UTF8.GetString(rawData));
}
aes.Clear();

return rawData;
}
}
}
}

客户端代码(爱丽丝):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Security.Cryptography;
using System.IO;

namespace ClientAlice
{
class Program
{
static CngKey aliceKey; // client private key

static byte[] alicePubKeyBlob; // client public key
static byte[] bobPubKeyBlob; // server public key
static byte[] symetricKey; // the symetric key that we want to give to the server securely

static void Main(string[] args)
{
//create the client private and public keys
CreateKeys();

// initialice the server's public key we will need it later
bobPubKeyBlob = new byte[alicePubKeyBlob.Length];

// connect to the server and open a stream in order to comunicate with it
TcpClient alice = new TcpClient("192.168.0.120", 54540);
var stream = alice.GetStream();

// send to the server the public key (client's public key)
stream.Write(alicePubKeyBlob, 0, alicePubKeyBlob.Length);

// now wait to receive the server's public key
stream.Read(bobPubKeyBlob, 0, bobPubKeyBlob.Length);

// create a random symetric key
symetricKey = new byte[1000];
Random r = new Random();
r.NextBytes(symetricKey);

// Encrypt the symetric key with the server's public key
byte[] encrytpedData = AliceSendsData(symetricKey);

// once encrypted send that encrypted data to the server. The only one that is going to be able to unecrypt that will be the server
stream.Write(encrytpedData, 0, encrytpedData.Length);

// not the server and client should have the same symetric key
}


private static void CreateKeys()
{
aliceKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
alicePubKeyBlob = aliceKey.Export(CngKeyBlobFormat.EccPublicBlob);
}

private static byte[] AliceSendsData(byte[] rawData)
{

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: {0}",
Convert.ToBase64String(symmKey));

using (var aes = new AesCryptoServiceProvider())
{
aes.Key = symmKey;
aes.GenerateIV();
using (ICryptoTransform encryptor = aes.CreateEncryptor())
using (MemoryStream ms = new MemoryStream())
{
// create CryptoStream and encrypt data to send
var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);

// write initialization vector not encrypted
ms.Write(aes.IV, 0, aes.IV.Length);
cs.Write(rawData, 0, rawData.Length);
cs.Close();
encryptedData = ms.ToArray();
}
aes.Clear();
}
}
Console.WriteLine("Alice: message is encrypted: {0}",
Convert.ToBase64String(encryptedData)); ;
Console.WriteLine();
return encryptedData;
}
}
}

也许我应该使用 ssl 连接。我认为我们在创建此类程序时学到了很多东西。我想知道这种技术是否是 Alice 以安全方式向 Bob 提供对称 key 的安全方式。

最佳答案

您的代码受 man-in-the-middle attacks 约束. SSL 通过依赖受信任的第三方并通过检查证书链直至受信任的根来验证公钥来解决此问题。因此,您最好的选择是 (a) 采用 SSL 并使用它,以及 (b) 通过阅读安全书籍(首先)而不是通过实现您自己的算法来学习。

关于c# - 以安全的方式在服务器和客户端之间交换对称 key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7540519/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com