/// <summary> /// Decrypt a block using ECB /// </summary> /// <param name="block">The block to decrypt</param> /// <param name="previousBlock">The previous block for the decryption chain</param> /// <param name="key">The key to decrypt with</param> /// <returns>The block decrypted with the key and previous block</returns> private byte[] AES_CBC_Decrypt(byte[] block, byte[] previousBlock, byte[] key) { // ECB Decrypt byte[] decryptedBlock = Cryptography.AES_ECB(block, key, false); // XOR block against the previous block return(challenge2.XORByteArray(decryptedBlock, previousBlock)); }
/// <summary> /// Encrypt a block using ECB /// </summary> /// <param name="block">The block to encrypt</param> /// <param name="previousBlock">The previous block for the encryption chain</param> /// <param name="key">The key to encrypt with</param> /// <returns>The block encrypted with the key and previous block</returns> private byte[] AES_CBC_Encrypt(byte[] block, byte[] previousBlock, byte[] key) { // XOR block against the previous block byte[] xorBlock = challenge2.XORByteArray(block, previousBlock); // ECB Encrypt return(Cryptography.AES_ECB(xorBlock, key)); }
/// <summary> /// Encrypts a string, while also appending an unknown string to the end of it /// </summary> /// <param name="text">The string to encrypt (the unknown string is appended to this)</param> /// <returns>The encryption of the text provided, after an unknown string was appended to it</returns> public byte[] Oracle(string text) { // Add unknown bytes text += Convert.FromBase64String(base64Text).GetASCIIString(); // Encrypt byte[] output = Cryptography.AES_ECB(text.GetBytes(), key); // Pad the bytes so it is a multiple of the block size return(challenge9.PadBytesToBlockSizeMultiple(output, 16)); // The Oracle knows the block size, as the Oracle knows all! }
/// <summary> /// Return an encrypted, JSON profile for the email provided /// </summary> /// <param name="email">The email of the user to get/create</param> /// <returns>The encrypted, JSON profile</returns> private byte[] profile_for(string email) { // Remove meta characters email = email.Replace("&", "").Replace("=", ""); // Create profile Profile profile = new Profile(email, 10, "user"); // Encode profile as JSON string profileJson = JsonSerializer.Serialize(profile); // Return the JSON profile, as an encrypted ASCII string return(Cryptography.AES_ECB(DecodeJSON_Profile(profileJson).GetBytes(), key)); }
/// <inheritdoc cref="IChallenge13.Attacker(byte[])"/> public string Attacker(byte[] encryptedProfileBytes) { // Contrsuct a block containing admin value with padding byte[] adminValueBytes = "admin".GetBytes(); byte[] adminPadded = challenge9.PadBytes(16, adminValueBytes); byte[] adminValueCipher = Cryptography.AES_ECB(adminPadded, key); // Construct the ciphertext with the last block containing user ciphertext with admin + padding ciphertext byte[] constructed = new byte[encryptedProfileBytes.Length + 16]; Array.Copy(encryptedProfileBytes, 0, constructed, 0, encryptedProfileBytes.Length); Array.Copy(adminValueCipher, 0, constructed, encryptedProfileBytes.Length - 16, 16); // Decrypt it to validate byte[] adminDecrypted = Cryptography.AES_ECB(constructed, key, false); string adminCipherText = adminDecrypted.GetASCIIString(); // Decrypt encrypted profile bytes for output string decryptedProfilePlainText = Cryptography.AES_ECB(encryptedProfileBytes, key, false).GetASCIIString(); // Return formatted output return(FormatOutput(encryptedProfileBytes.GetASCIIString(), decryptedProfilePlainText, constructed.GetASCIIString(), adminCipherText)); }
/// <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)); }
/// <summary> /// Encrypt/Decrypt bytes using AES in ECB mode /// </summary> /// <param name="bytes">The bytes to encrypt/decrypt</param> /// <param name="key">The key to use for encrypting/decrypting</param> /// <param name="encrypt">Whether we are encrypting or decrypting</param> /// <returns>The encrypted/decrypted data</returns> public byte[] AES_ECB(byte[] bytes, byte[] key, bool encrypt) { return(Cryptography.AES_ECB(bytes, key, encrypt)); }