/// <summary> /// Encrypts data into an <see cref="IEnumerable"/> of <see cref="Fingerprint"/>'s. /// </summary> /// <param name="data">The data you want to encrypt.</param> /// <param name="key">A 256 bit random Key to encrypt the data. You can use the <see cref="GenerateNewKey"/> method to generate one.</param> /// <param name="iv">A 128 bit random IV. You can use the <see cref="GenerateNewIv"/> method to generate one.</param> public IEnumerable<Fingerprint> Encrypt(byte[] data, byte[] key, byte[] iv) { // Validate data parameter if (data == null) throw new ArgumentNullException("data"); if (data.Length == 0) return new List<Fingerprint>(); // Validate key parameter if (key == null) throw new ArgumentNullException("key"); if (key.Length == 0) throw new ArgumentException("The key parameter can not be empty.", "key"); if (key.Length * 8 != KeyBitSize) throw new ArgumentException($"The key parameter must be {KeyBitSize} bits long.", "key"); // Validate iv parameter if (iv == null) throw new ArgumentNullException("iv"); if (iv.Length == 0) throw new ArgumentException("The iv parameter can not be empty.", "iv"); if (iv.Length * 8 != BlockBitSize) throw new ArgumentException($"The iv parameter must be {BlockBitSize} bits long.", "iv"); // Encrypt data with AES var encryptedData = EncryptPayload(data, key, iv); // Calculate padding length needed for the encrypted data var length = encryptedData.Length; var paddingLength = 10 - (length % 10); if (paddingLength <= 0) paddingLength = 10; Array.Resize(ref encryptedData, length + paddingLength); // Create cryptographically random padding var padding = new byte[paddingLength]; _randomNumberGenerator.GetBytes(padding); padding[paddingLength - 1] = (byte) paddingLength; Array.Copy(padding, 0, encryptedData, length, padding.Length); // Create BitArray of the encrypted data var encryptedDataBitArray = new BitArray(encryptedData); var fingerprints = new List<Fingerprint>(); // Check to make sure the number of bits in the file is divisible by 10 if (encryptedDataBitArray.Length % 10 != 0) throw new InvalidOperationException(); for (var i = 0; i < encryptedDataBitArray.Length;) { var blockBitArray = new BitArray(new bool[] { encryptedDataBitArray.Get(i++), // 0x00 encryptedDataBitArray.Get(i++), // 0x01 encryptedDataBitArray.Get(i++), // 0x02 encryptedDataBitArray.Get(i++), // 0x03 encryptedDataBitArray.Get(i++), // 0x04 encryptedDataBitArray.Get(i++), // 0x05 encryptedDataBitArray.Get(i++), // 0x06 encryptedDataBitArray.Get(i++), // 0x07 encryptedDataBitArray.Get(i++), // 0x08 encryptedDataBitArray.Get(i++) // 0x09 }); fingerprints.Add( _fingerprintManager.GetFromIndex(blockBitArray.ToInt16())); } return fingerprints; }