private void KeyExchange()
{
if (session == null) {
throw new Exception("Session seems not start, Please start Session first.");
}
Hashtable sessionObject;
InitKeylen();
if (encrypt) {
DHParams dhParams = new DHParams(keylen);
keylen = dhParams.GetL();
BigInteger p = dhParams.GetP();
BigInteger g = dhParams.GetG();
BigInteger x = dhParams.GetX();
BigInteger y = g.ModPow(x, p);
sessionObject = new Hashtable();
sessionObject["x"] = x;
sessionObject["p"] = p;
sessionObject["keylen"] = keylen;
session.Contents[cid] = sessionObject;
Hashtable dhp = dhParams.GetDHParams();
dhp["y"] = y.ToString();
buffer.Append("phprpc_encrypt=\"");
buffer.Append(EncodeString(Serialize(dhp)));
buffer.Append("\";\r\n");
if (keylen != 128) {
buffer.Append("phprpc_keylen=\"");
buffer.Append(keylen);
buffer.Append("\";\r\n");
}
SendURL();
}
else {
sessionObject = (Hashtable)session.Contents[cid];
lock (sessionObject.SyncRoot) {
BigInteger x = (BigInteger)sessionObject["x"];
BigInteger p = (BigInteger)sessionObject["p"];
if (keylen == 128) {
key = new byte[16];
Byte[] k = y.ModPow(x, p).GetBytes();
for (Int32 i = 1, n = Math.Min(k.Length, 16); i <= n; i++) {
this.key[16 - i] = k[n - i];
}
}
else {
key = MD5.Hash(Encoding.ASCII.GetBytes(y.ModPow(x, p).ToString()));
}
sessionObject["key"] = key;
sessionObject.Remove("x");
sessionObject.Remove("p");
session.Contents[cid] = sessionObject;
}
}
SendCallback();
}