//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); }
/// <summary> /// Returns the key whos date field is equal to todays date. If a key does not yet exist for todays date, it is created /// and stored. /// </summary> /// <returns>byte[] containing todays key</returns> public Key getTodaysKey() { SQLiteDataReader reader = db.retrieve("SELECT keyID, AESKey, IV FROM Keys WHERE date = CURRENT_DATE"); //gets key with todays date if (reader.HasRows) //if there were any keys with todays date { reader.Read(); //prepares reader to extract data int keyID = Convert.ToInt32((long)reader["keyID"]); //sqlite stored primary keys as int64s byte[] encKey = (byte[])reader["AESKey"]; //extract encrypted key byte[] IV = (byte[])reader["IV"]; //extract initialisation vector it was encrypted with byte[] keyBytes = decryptKey(encKey, IV); //decrypt key Key key = new Key(keyID, keyBytes); //creates key object to return return(key); } else //must generate new key and create DB entry { byte[] newKey = CryptoUtility.GenerateAESRandomKey(); //generate random AES key byte[] masterKey = Globals.getMasterKey(); //gets master key to encrypt the new key Tuple <byte[], byte[]> encResult = CryptoUtility.AESEncrypt(newKey, masterKey); //encrypts new key with master key byte[] encNewKey = encResult.Item1; //extract encrypted key byte[] IV = encResult.Item2; //extract initialisation vector insertNewKey(encNewKey, IV); //insert it into database return(getTodaysKey()); //1 level of recursion, creates entry then fetches and returns it } }
//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 message (which must have sender/recipient set) and stores it in the database. /// </summary> /// <param name="message">Message to store</param> public void commitMessage(Message message) { Boolean sent = false; //was received if (message.target != 0) //was sent { sent = true; } int conversationID; //ID of User the message was exchanged with if (sent) //was sent by this application { conversationID = message.target; //get ID of who it was sent to (ID of sender would be zero - aka local) } else //wat received by this applicaiton { conversationID = message.sender; //gets ID of sender (ID of target would be zero - aka local) } Key key = keyManager.getTodaysKey(); //get key being used at time of inserting message byte[] plainMessageBytes = Encoding.UTF8.GetBytes(message.message); //convert message text into byte array Tuple <byte[], byte[]> encResult = CryptoUtility.AESEncrypt(plainMessageBytes, key.keyBytes); //encrypt message with todays key byte[] encMessage = encResult.Item1; //extract encrypted message byte[] IV = encResult.Item2; //extract initialisation vector int keyID = key.keyID; key = null; //let the key bytes be garbage collected. //runs query and passes blobs to store message db.messageInsert($"INSERT INTO Messages (conversationID, sent, message, keyID, IV) VALUES (\"{conversationID}\",\"{sent}\",@message,\"{keyID}\",@IV)", encMessage, IV); //string messageString = message.message; //run query to store it //db.update($"INSERT INTO Messages (conversationID, sent, message) VALUES (\"{conversationID}\",\"{sent}\",\"{messageString}\")"); }
/// <summary> /// AES 加密(高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法) /// </summary> /// <param name="encryptString">待加密密文</param> /// <param name="encryptKey">加密密钥</param> /// <returns></returns> public static string AESEncrypt(this string encryptString, string encryptKey) { return(CryptoUtility.AESEncrypt(encryptString, encryptKey)); }