/// <inheritdoc /> public string Solve(string input) { // Convert input string to bytes byte[] bytes = input.GetBytes(); // Run Oracle against the input data multiple times (with different random byte keys) int totalTests = 50; int testFailCount = 0; for (int i = 0; i < totalTests; i++) { // Encrypt data using a random key int keySize = 16; Tuple <byte[], EncryptionTypeEnum> encryptionResult = EncryptWithUnknownKey(bytes, keySize); // Detect which encryption type was used EncryptionTypeEnum oracleEncryption = DetectEncryptionType(encryptionResult.Item1); // Get the actual encryption type that was used EncryptionTypeEnum actualEncryption = encryptionResult.Item2; // If the determination does not match, the test failed so increment the count if (!oracleEncryption.Equals(actualEncryption)) { testFailCount++; } } // Format the result of the tests and return it return(FormatOutput(totalTests, testFailCount)); }
/// <summary> /// Encrypt bytes using ECB and CBC randomly /// </summary> /// <param name="bytes">The bytes to encrypt</param> /// <param name="key">The key used to encrypt</param> /// <returns>A tuple containing the encrypted bytes and the encryption type used (ECB or CBC)</returns> private Tuple <byte[], EncryptionTypeEnum> EncryptBytesRandomly(byte[] bytes, byte[] key) { // Encrypt with ECB or CBC randomly byte[] encryptedBytes = new byte[bytes.Length]; EncryptionTypeEnum encryptionType = (EncryptionTypeEnum)random.Next(1, 3); // Encrypt if (encryptionType.Equals(EncryptionTypeEnum.ECB)) { // Encrypt using ECB encryptedBytes = Cryptography.AES_ECB(bytes, key); } else if (encryptionType.Equals(EncryptionTypeEnum.CBC)) { // Create an initialization vector (use random IV) byte[] iv = GenerateRandomASCIIBytes(key.Length); // Encrypt using CBC encryptedBytes = challenge10.AES_CBC(true, bytes, key, iv); } return(new Tuple <byte[], EncryptionTypeEnum>(encryptedBytes, encryptionType)); }