private T Decrypt(Byte[] ciphertext, PinnedBuffer key, SymmetricAlgorithmSpecification algorithm) { using (var cipher = algorithm.ToCipher(RandomnessProvider)) { using (var pinnedCiphertext = new PinnedBuffer(ciphertext, false)) { using (var plaintext = cipher.Decrypt(pinnedCiphertext, key)) { return(BinarySerializer.Deserialize(plaintext)); } } } }
private Byte[] Encrypt(T plaintextObject, PinnedBuffer key, SymmetricAlgorithmSpecification algorithm, Byte[] initializationVector) { var plaintext = BinarySerializer.Serialize(plaintextObject); var plaintextLength = plaintext.Length; using (var pinnedPlaintext = new PinnedBuffer(plaintextLength, true)) { Array.Copy(plaintext, pinnedPlaintext, plaintextLength); using (var cipher = algorithm.ToCipher(RandomnessProvider)) { switch (cipher.Mode) { case CipherMode.CBC: using (var processedInitializationVector = new PinnedBuffer(cipher.BlockSizeInBytes, true)) { if (initializationVector is null) { RandomnessProvider.GetBytes(processedInitializationVector); } else { Array.Copy(initializationVector.RejectIf(argument => argument.Length < cipher.BlockSizeInBytes, nameof(initializationVector)), processedInitializationVector, cipher.BlockSizeInBytes); } return(cipher.Encrypt(pinnedPlaintext, key, processedInitializationVector)); } case CipherMode.ECB: return(cipher.Encrypt(pinnedPlaintext, key, null)); default: throw new InvalidOperationException($"The specified cipher mode, {cipher.Mode}, is not supported."); } } } }