//does encryption and decryption and returns a filled testResult private TestResult process(String message) { TestResult testResult = new TestResult(); //encryption stopWatch.Start(); byte[] plainMessageBytes = Encoding.UTF8.GetBytes(message); //convert message to byte array Tuple <byte[], byte[]> res = CryptoUtility.AESEncrypt(plainMessageBytes, AESKey); //encrypts data //extract results byte[] encMessageBytes = res.Item1; //gets encrypted bytes from tuple byte[] IV = res.Item2; //gets initialisation vector from tuple stopWatch.Stop(); testResult.encryptionTime = (int)stopWatch.ElapsedMilliseconds; //store time taken testResult.totalLength = encMessageBytes.Length; //store length of encrypted message //decryption// stopWatch.Reset(); stopWatch.Start(); //passes back encrypted message, key and initialisation vector to decrypt it string decryptedMessage = CryptoUtility.AESDecrypt(encMessageBytes, AESKey, IV); stopWatch.Stop(); testResult.decryptionTime = (int)stopWatch.ElapsedMilliseconds; //check that nothing went wrong if (0 != String.Compare(decryptedMessage, message)) { throw new Exception("something ain't right"); } testResult.totalTime = testResult.encryptionTime + testResult.decryptionTime; //adds up total time return(testResult); }
//reads contact info from database and creates Contact objects private void loadContacts() { contactsList.Clear(); //empty list, if reading from database might as well reload everything SQLiteDataReader reader = db.retrieve("SELECT * FROM Users"); //gets all user records //if(reader.HasRows) //if any data was read from the DB Contact contact; //temporary contact object to add to list while (reader.Read()) //iterate over each tuple returned from the database { int ID = Convert.ToInt32((long)reader["userID"]); //sqlite handles primary key field as int64 byte[] encUsername = (byte[])reader["username"]; byte[] encIPAddress = (byte[])reader["IPAddress"]; byte[] IV = (byte[])reader["IV"]; //initialisation vector encUsername and ecnIPAddress were encrypted with byte[] masterKey = Globals.getMasterKey(); //decrypts and gets master key string username = CryptoUtility.AESDecrypt(encUsername, masterKey, IV); //decrypt username string IPAddress = CryptoUtility.AESDecrypt(encIPAddress, masterKey, IV); //decrypt IPAddress contact = new Contact(ID, username, IPAddress); //puts contact info into object contactsList.Add(contact); } }
//this method tests the creation of a random AES key, then using it encrypt and decrypt a message public void testRandomKeyEncryption() { string data = "hello, good morning, I hope all is well. blahblahblahblahblah"; byte[] dataBytes = Encoding.UTF8.GetBytes(data); //convert data to bytes byte[] keyBytes = CryptoUtility.GenerateAESRandomKey(); //gets randomly generated //tuple contains encrypted bytes plus initialisation vector needed to decrypt it Tuple <byte[], byte[]> enc = CryptoUtility.AESEncrypt(dataBytes, keyBytes); //encypts and gets encrypted bytes + IV byte[] encBytes = enc.Item1; //encrypted bytes byte[] IV = enc.Item2; //Instantiation vector string decryptedString = CryptoUtility.AESDecrypt(encBytes, keyBytes, IV); Assert.AreEqual <string>(data, decryptedString); //compare original data to the decrypted string }
/// <summary> /// Takes a contact and returns a list containg all messages exchanged between local and contact. /// </summary> /// <param name="contact">Contace for which to get history of exchanges messages</param> /// <returns>List of messages associated with the provided contact</returns> public List <Message> getMessageHistory(Contact contact) { List <Message> messages = new List <Message>(); Message message; //temp var to hold messages before being put into list //for <contactID> select every message, initialisation vector to decrypt the message, the ID of the key it's encrypted with, and bool if it was sent or received SQLiteDataReader reader = db.retrieve($"SELECT sent, message, IV, keyID FROM Messages WHERE (conversationID = \"{contact.ID}\")"); //API BUG - SELECT with explicit fields fails ONLY when the fields are in brackets, lord knows why while (reader.Read()) //iterate over all existing records { bool sent = (bool)reader["sent"]; //extract if message was sent or received byte[] encMessageBytes = (byte[])reader["message"]; //extract message byte[] messageIV = (byte[])reader["IV"]; //extract initialisation vector for message int keyID = Convert.ToInt32((long)reader["keyID"]); //extract ID of key that encrypted message. sqlite handles forien keys to primary keys as int64. byte[] messageKey = keyManager.getKey(keyID); //gets plain key from manager (must be discarded once done with) //passes encrypted message bytes, plain key and IV to CryptoUtility and gets decrypted message in return string messageString = CryptoUtility.AESDecrypt(encMessageBytes, messageKey, messageIV); messageKey = null; //garbage collect key bytes int senderID; int targetID; if (sent) //message was sent by local { senderID = 0; targetID = contact.ID; } else //message was sent by contact { senderID = contact.ID; targetID = 0; } message = new Message(messageString, senderID, targetID); //create the message object messages.Add(message); //store it in list } return(messages); }
/// <summary> /// AES 解密(高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法) /// </summary> /// <param name="decryptString">待解密密文</param> /// <param name="decryptKey">解密密钥</param> /// <returns></returns> public static string AESDecrypt(this string decryptString, string decryptKey) { return(CryptoUtility.AESDecrypt(decryptString, decryptKey)); }