İki yıl sonra geri gelip cevapları kabul edeceğinizden şüpheliyim, ancak ne soruyorsun diye sordum, ve bunun oldukça yaygın bir sorun olduğunu düşünüyorum, bu yüzden bunu başkalarının yararı için gönderiyorum bu soru boyunca.
GregS'in bilgilerini uygulamaya dahil ettim. Belirli bir amaç için, Initialize yöntemini yapıcınız yapar, net & diffie-hellman kodunu çıkarır ve önceden paylaşılmış anahtarınızı Aes nesnesine atar (oluşturulan anahtar yerine).
AES258'e (AES128'e benzer güçte olma tehlikesiyle karşı karşıya olmasına rağmen (AES256 kullanıyorum) (anahtarlarınız yanlış uygulama nedeniyle ilgiliyse, benimkileri bilmediğim için). NSA'nın kendi özellikleriyle uğraşıp karıştırılmadığını öğrenmek için NIST'e güvenmiyorsanız, AES'i KULLANMAYIN.
Ayrıca, bu bir başlangıç noktasıdır! .NET'te bir NetworkStream üzerinden şifrelenmiş veri gönderme sık karşılaşılan sorun üzerinde çalışıyorum!
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
namespace FullDuplexCrypto
{
class CryptoNetworkStream : Stream
{
public CryptoNetworkStream(IPAddress address, int port)
{
Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
socket.Connect(address, port);
//socket.NoDelay = true;
Initialize(new NetworkStream(socket, true));
}
public CryptoNetworkStream(Socket socket)
{
Initialize(new NetworkStream(socket, true));
}
private void Initialize(Stream stream)
{
underlyer = stream;
using(ECDiffieHellmanCng dh = new ECDiffieHellmanCng())
{
dh.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
dh.HashAlgorithm = CngAlgorithm.Sha256;
byte[] buffer = dh.PublicKey.ToByteArray();
underlyer.Write(buffer, 0, buffer.Length);
underlyer.Read(buffer, 0, buffer.Length);
using(Aes aes = Aes.Create())
{
aes.KeySize = 256;
aes.Key = dh.DeriveKeyMaterial(CngKey.Import(buffer, CngKeyBlobFormat.EccPublicBlob));
aes.FeedbackSize = 8;
aes.Mode = CipherMode.CFB;
underlyer.Write(aes.IV, 0, aes.IV.Length);
encrypter = new CryptoStream(underlyer, aes.CreateEncryptor(), CryptoStreamMode.Write);
underlyer.Read(aes.IV, 0, aes.IV.Length);
decrypter = new CryptoStream(underlyer, aes.CreateDecryptor(), CryptoStreamMode.Read);
}
}
}
private Stream underlyer;
private Stream encrypter;
private Stream decrypter;
public override bool CanRead { get { return decrypter.CanRead; } }
public override bool CanWrite { get { return encrypter.CanWrite; } }
public override bool CanSeek { get { return underlyer.CanSeek; } }
public override long Length { get { return underlyer.Length; } }
public override long Position { get { return underlyer.Position; } set { underlyer.Position = value; } }
public override void Flush()
{
encrypter.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
return decrypter.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
encrypter.Write(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
return underlyer.Seek(offset, origin);
}
public override void SetLength(long value)
{
underlyer.SetLength(value);
}
private bool isDisposed = false;
protected override void Dispose(bool isDisposing)
{
if(!isDisposed)
{
if(isDisposing)
{
// Release managed resources.
encrypter.Dispose();
decrypter.Dispose();
underlyer.Dispose();
}
// Release unmanaged resources.
isDisposed = true;
}
base.Dispose(isDisposing);
}
}
}
neden kabul edilemez iki akım yaratmaktadır: fazla uzatmadan yüz on iki satır ya da daha az
? Böyle bir durumda, genellikle burada gerçekleşen iki "oturum" için farklı şifreleme anahtarları ayarlamak isterdim (örneğin, anahtar olarak "HASH (passphrase + '||' + gönderici adı)" anahtarını kullan) –@Damien çünkü bunun üzerinde daha fazla akıntım var ve bunların hepsini çoğaltmak istemiyorum. –
, Okuma ve Yazmayı destekleyen (ancak, büyük olasılıkla aramaz) tek bir akış nesnesinin semantiğine ihtiyacınız varsa, ancak bu işlemleri, yalnızca yapımında kendisine iletilmiş bir "ReadStream" veya "WriteStream" e dönüştürür. yazmak için kod veya benzeri bir sayfa alın. Böylece, şifrelemeyi kanalın her iki tarafına eklemek için Kripto sınıflarını kullanabilir ve daha sonra bu diğer sınıfı, daha yüksek katmanlara tek bir akış olarak sunmak için kullanabilirsiniz. –