// format: 27 char: hash, 6 char: ID, 12 char: count, rest for message; public static string FormMessage(ulong messageNumber, string text, bool isServer) { var toHash = (isServer ? SERVER_ID : CLIENT_ID) + Convert.ToBase64String(BitConverter.GetBytes(messageNumber)) + text; return(HashedMessage.FormMessage(toHash)); }
/// <summary> /// Client: /// 1) send: "client"||R1 /// 2) recieve R2 || HE("server" || R1, K_pass) /// 2.1 check R1 /// 2.2 check ID_server for "server" and size /// 3) send HE("client" || R2 || RSA_public, k_pass) /// 4) recieve HE("server" || E(Key_session || IV_session, RSA_public), k_pass) /// /// HE(x||y, k) --> E(H(x||y)||x||y, k) /// /// </summary> /// <returns>true if key exchange is succssesful</returns> public bool exchangeKeys() { sessionId_ = isServer ? SERVER : CLIENT; if (isServer) { string messageRecieved = streamReader.ReadLine(); //1 var others_sessionID = messageRecieved.Substring(0, SESSION_ID_LENGTH); string random1 = messageRecieved.Substring(SESSION_ID_LENGTH); if (random1.Length != RANDOM_SIZE_BASE64) { return(false); } if (others_sessionID != CLIENT) { return(false); } string random2 = generateRandomString(RANDOM_SIZE_BYTES); string messageEncrypted = passAES.Encrypt(HashedMessage.FormMessage(sessionId_ + random1)); streamWriter.WriteLine(random2 + messageEncrypted); //2 streamWriter.Flush(); var hashedMessage = new HashedMessage(passAES.Decrypt(streamReader.ReadLine())); //3 messageRecieved = hashedMessage.Message; if (!hashedMessage.hashMatched) { return(false); } if (messageRecieved.Substring(0, SESSION_ID_LENGTH) != others_sessionID) { return(false); } string receivedRandom2 = messageRecieved.Substring(SESSION_ID_LENGTH, RANDOM_SIZE_BASE64); if (random2 != receivedRandom2) { return(false); } string rsaPublic = messageRecieved.Substring(SESSION_ID_LENGTH + RANDOM_SIZE_BASE64); RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(rsaPublic); if (verbose) { Console.WriteLine("RSA Public Key: " + rsaPublic + "\n"); } sessionAES = new SimpleAES(aesKeySize); sessionAES.verbose = verbose; string encryptedPart = Convert.ToBase64String(rsa.Encrypt(sessionAES.key, true)); streamWriter.WriteLine(passAES.Encrypt(HashedMessage.FormMessage(sessionId_ + encryptedPart))); //4 streamWriter.Flush(); if (verbose) { Console.WriteLine("SessionKey: " + Convert.ToBase64String(sessionAES.key)); } } else ///client { string random1 = generateRandomString(RANDOM_SIZE_BYTES); streamWriter.WriteLine(sessionId_ + random1); // 1 streamWriter.Flush(); string messageRecieved = streamReader.ReadLine(); //2 string random2 = messageRecieved.Substring(0, RANDOM_SIZE_BASE64); string messageEncrypted = messageRecieved.Substring(RANDOM_SIZE_BASE64); messageRecieved = passAES.Decrypt(messageEncrypted); // ID_server || R1 var hashedMessage = new HashedMessage(messageRecieved); messageRecieved = hashedMessage.Message; if (!hashedMessage.hashMatched) { return(false); } var others_sessionID = messageRecieved.Substring(0, SESSION_ID_LENGTH); if (others_sessionID != SERVER) //2.2 { return(false); } string recievedRandom1 = messageRecieved.Substring(SESSION_ID_LENGTH); if (recievedRandom1 != random1) // 2.1 { return(false); } RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(rsaKeySize); string publicKey = rsa.ToXmlString(false); if (verbose) { Console.WriteLine("RSA Public Key: " + publicKey + "\n"); } string message = sessionId_ + random2 + publicKey; streamWriter.WriteLine(passAES.Encrypt(HashedMessage.FormMessage(message))); // 3 streamWriter.Flush(); hashedMessage = new HashedMessage(passAES.Decrypt(streamReader.ReadLine())); //4 messageRecieved = hashedMessage.Message; //4 if (messageRecieved.Substring(0, SESSION_ID_LENGTH) != others_sessionID) { return(false); } string restOfMessage = messageRecieved.Substring(SESSION_ID_LENGTH); byte[] sessionKey = rsa.Decrypt(Convert.FromBase64String(restOfMessage), true); sessionAES = new SimpleAES(sessionKey); sessionAES.verbose = verbose; if (verbose) { Console.WriteLine("SessionKey: " + Convert.ToBase64String(sessionAES.key)); } } return(true); }