过程 :
1.Client 端向server 端请求公钥pubKey
2.Client 端生成随机对称密钥 (symetricKey) ,然后用pubkey将其加密为EncryptedSymetricKey。
3.Client 端向server 端发送EncryptedSymetricKey
4.Server 端用privateKey解密EncryptedSymetricKey,从而得到symetricKey
5.Client ,Server 用symetricKey 加密传输数据
6.Client ,server 之间的加密数据通道建立。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Security.Cryptography;
using System.Xml.Serialization;
namespace HttpsSimpleServer
{
public class Server
{
string publickKey;
RSACryptoServiceProvider RSA;
byte[] de_key;
byte[] de_iv;
Encoding encoder = Encoding.Default;
public void GenerateKeys()
{
RSA = new RSACryptoServiceProvider();
RSAParameters RSAParams = RSA.ExportParameters(false);
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
XmlSerializer serializer = new XmlSerializer(typeof(RSAParameters));
serializer.Serialize(sw, RSAParams);
publickKey = sb.ToString();
}
public byte[] EncryptTextToMemory(string Data, byte[] Key, byte[] IV)
{
try
{
// Create a MemoryStream.
MemoryStream mStream = new MemoryStream();
// Create a CryptoStream using the MemoryStream
// and the passed key and initialization vector (IV).
CryptoStream cStream = new CryptoStream(mStream,
new TripleDESCryptoServiceProvider().CreateEncryptor(Key, IV),
CryptoStreamMode.Write);
// Convert the passed string to a byte array.
byte[] toEncrypt = encoder.GetBytes(Data);
// Write the byte array to the crypto stream and flush it.
cStream.Write(toEncrypt, 0, toEncrypt.Length);
cStream.FlushFinalBlock();
// Get an array of bytes from the
// MemoryStream that holds the
// encrypted data.
byte[] ret = mStream.ToArray();
// Close the streams.
cStream.Close();
mStream.Close();
// Return the encrypted buffer.
return ret;
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
}
public string DecryptTextFromMemory(byte[] Data, byte[] Key, byte[] IV)
{
try
{
// Create a new MemoryStream using the passed
// array of encrypted data.
MemoryStream msDecrypt = new MemoryStream(Data);
// Create a CryptoStream using the MemoryStream
// and the passed key and initialization vector (IV).
CryptoStream csDecrypt = new CryptoStream(msDecrypt,
new TripleDESCryptoServiceProvider().CreateDecryptor(Key, IV),
CryptoStreamMode.Read);
// Create buffer to hold the decrypted data.
byte[] fromEncrypt = new byte[Data.Length];
// Read the decrypted data out of the crypto stream
// and place it into the temporary buffer.
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
//Convert the buffer into a string and return it.
return encoder.GetString(fromEncrypt);
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
}
public void WaitRequest()
{
if (!HttpListener.IsSupported)
{
Console.WriteLine("Windows XP SP2 or Server 2003 is required to use the HttpListener class.");
return;
}
GenerateKeys();
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://localhost:8080/index/");
while (true)
{
listener.Start();
Console.WriteLine("Listening...");
HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;
// Obtain a response object.
string inputVal = string.Empty;
string responseString = string.Empty;
using (StreamReader sr = new StreamReader(request.InputStream))
{
inputVal = sr.ReadToEnd();
if (inputVal == "ReqPublicKey")
{
responseString = publickKey;
Console.WriteLine("sent public key.");
}
else if(inputVal.IndexOf("symetricKey")!=-1)
{
byte[] key = Convert.FromBase64String(inputVal.Split(new char[] { ',' })[1]);
byte[] iv = Convert.FromBase64String(inputVal.Split(new char[] { ',' })[2]);
de_key= RSA.Decrypt(key, true);
de_iv = RSA.Decrypt(iv, true);
Console.WriteLine("received symetricKey." +encoder.GetString(de_key));
responseString = "received symetricKey";
}
else if (inputVal.IndexOf("PackedData") != -1)
{
byte[] rawData = Convert.FromBase64String(inputVal.Split(new char[] { ',' })[1]);
string de_txt = DecryptTextFromMemory(rawData, de_key, de_iv);
byte[] toClient_buff= EncryptTextToMemory("ACK:" + de_txt, de_key, de_iv);
Console.WriteLine("ACK :");
responseString = Convert.ToBase64String(toClient_buff);
}
}
HttpListenerResponse response = context.Response;
Console.WriteLine("in network:" + responseString);
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
System.IO.Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
output.Close();
listener.Stop();
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.Cryptography;
namespace HttpsSimpleServer
{
public class CryptoHelper
{
public static void EncryptTextToFile(String Data, String FileName, byte[] Key, byte[] IV)
{
try
{
// Create or open the specified file.
FileStream fStream = File.Open(FileName, FileMode.OpenOrCreate);
// Create a CryptoStream using the FileStream
// and the passed key and initialization vector (IV).
CryptoStream cStream = new CryptoStream(fStream,
new TripleDESCryptoServiceProvider().CreateEncryptor(Key, IV),
CryptoStreamMode.Write);
// Create a StreamWriter using the CryptoStream.
StreamWriter sWriter = new StreamWriter(cStream);
// Write the data to the stream
// to encrypt it.
sWriter.WriteLine(Data);
// Close the streams and
// close the file.
sWriter.Close();
cStream.Close();
fStream.Close();
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file access error occurred: {0}", e.Message);
}
}
public static string DecryptTextFromFile(String FileName, byte[] Key, byte[] IV)
{
try
{
// Create or open the specified file.
FileStream fStream = File.Open(FileName, FileMode.OpenOrCreate);
// Create a CryptoStream using the FileStream
// and the passed key and initialization vector (IV).
CryptoStream cStream = new CryptoStream(fStream,
new TripleDESCryptoServiceProvider().CreateDecryptor(Key, IV),
CryptoStreamMode.Read);
// Create a StreamReader using the CryptoStream.
StreamReader sReader = new StreamReader(cStream);
// Read the data from the stream
// to decrypt it.
string val = sReader.ReadLine();
// Close the streams and
// close the file.
sReader.Close();
cStream.Close();
fStream.Close();
// Return the string.
return val;
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file access error occurred: {0}", e.Message);
return null;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Security.Cryptography;
using System.Xml.Serialization;
namespace HttpSimpleClient
{
public class Client
{
public string someData = "i love this game!hahax!@#$66郝臖6";
public string publicKeyFromServer;
TripleDESCryptoServiceProvider tDESalg = new TripleDESCryptoServiceProvider();
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
Encoding encoder = Encoding.Default;
public Client()
{
}
public void RequestPublicKey()
{
// Create a new 'Uri' object with the specified string.
Uri myUri = new Uri("http://localhost:8080/index/");
// Create a new request to the above mentioned URL.
WebRequest myWebRequest = WebRequest.Create(myUri);
myWebRequest.Method = "POST";
using (StreamWriter sw = new StreamWriter(myWebRequest.GetRequestStream(),encoder))
{
sw.Write("ReqPublicKey");
}
WebResponse myWebResponse = myWebRequest.GetResponse();
using (StreamReader sr = new StreamReader(myWebResponse.GetResponseStream(), encoder))
{
publicKeyFromServer = sr.ReadToEnd();
}
}
public void SendEncryptSymetricKeyWithPublicKey()
{
XmlSerializer serializer = new XmlSerializer(typeof(RSAParameters));
StringReader sr = new StringReader(publicKeyFromServer);
RSAParameters RSAParams2 = (RSAParameters)serializer.Deserialize(sr);
RSA.ImportParameters(RSAParams2);
byte[] key = RSA.Encrypt(tDESalg.Key, true);
byte[] iv = RSA.Encrypt(tDESalg.IV, true);
string relString = "symetricKey";
relString += "," + Convert.ToBase64String(key);
relString += "," + Convert.ToBase64String(iv);
// Create a new 'Uri' object with the specified string.
Uri myUri = new Uri("http://localhost:8080/index/");
// Create a new request to the above mentioned URL.
WebRequest myWebRequest = WebRequest.Create(myUri);
myWebRequest.Method = "POST";
using (StreamWriter sw = new StreamWriter(myWebRequest.GetRequestStream(), encoder))
{
sw.Write(relString);
}
WebResponse myWebResponse = myWebRequest.GetResponse();
using (StreamReader sr2 = new StreamReader(myWebResponse.GetResponseStream(), encoder))
{
string ack = sr2.ReadToEnd();
Console.WriteLine(ack);
}
}
public void SendEncryptedData()
{
byte[] symetric_enc_data= EncryptTextToMemory(someData, tDESalg.Key, tDESalg.IV);
string relString = "PackedData";
relString += "," + Convert.ToBase64String(symetric_enc_data);
// Create a new 'Uri' object with the specified string.
Uri myUri = new Uri("http://localhost:8080/index/");
// Create a new request to the above mentioned URL.
WebRequest myWebRequest = WebRequest.Create(myUri);
myWebRequest.Method = "POST";
using (StreamWriter sw = new StreamWriter(myWebRequest.GetRequestStream(), encoder))
{
Console.WriteLine("sent data:" + someData);
sw.Write(relString);
}
WebResponse myWebResponse = myWebRequest.GetResponse();
using (StreamReader sr2 = new StreamReader(myWebResponse.GetResponseStream(), encoder))
{
string ack = sr2.ReadToEnd();
byte[] ack_buff = Convert.FromBase64String(ack);
Console.WriteLine("in network:" + ack);
string de_txt = DecryptTextFromMemory(ack_buff, tDESalg.Key, tDESalg.IV);
Console.WriteLine(de_txt);
}
}
public byte[] EncryptTextToMemory(string Data, byte[] Key, byte[] IV)
{
try
{
// Create a MemoryStream.
MemoryStream mStream = new MemoryStream();
// Create a CryptoStream using the MemoryStream
// and the passed key and initialization vector (IV).
CryptoStream cStream = new CryptoStream(mStream,
new TripleDESCryptoServiceProvider().CreateEncryptor(Key, IV),
CryptoStreamMode.Write);
// Convert the passed string to a byte array.
byte[] toEncrypt = encoder.GetBytes(Data);
// Write the byte array to the crypto stream and flush it.
cStream.Write(toEncrypt, 0, toEncrypt.Length);
cStream.FlushFinalBlock();
// Get an array of bytes from the
// MemoryStream that holds the
// encrypted data.
byte[] ret = mStream.ToArray();
// Close the streams.
cStream.Close();
mStream.Close();
// Return the encrypted buffer.
return ret;
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
}
public string DecryptTextFromMemory(byte[] Data, byte[] Key, byte[] IV)
{
try
{
// Create a new MemoryStream using the passed
// array of encrypted data.
MemoryStream msDecrypt = new MemoryStream(Data);
// Create a CryptoStream using the MemoryStream
// and the passed key and initialization vector (IV).
CryptoStream csDecrypt = new CryptoStream(msDecrypt,
new TripleDESCryptoServiceProvider().CreateDecryptor(Key, IV),
CryptoStreamMode.Read);
// Create buffer to hold the decrypted data.
byte[] fromEncrypt = new byte[Data.Length];
// Read the decrypted data out of the crypto stream
// and place it into the temporary buffer.
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
//Convert the buffer into a string and return it.
return encoder.GetString(fromEncrypt);
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace HttpSimpleClient
{
class Program
{
static void Main(string[] args)
{
Client client = new Client();
client.RequestPublicKey();
client.SendEncryptSymetricKeyWithPublicKey();
client.SendEncryptedData();
Console.Read();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace HttpsSimpleServer
{
class Program
{
static void Main(string[] args)
{
Server server = new Server();
server.WaitRequest();
}
}
}