private CascadingSymmetricKey(SecureSymmetricKeyDerivationMode derivationMode, params SymmetricAlgorithmSpecification[] algorithms)
            : base(ConcurrencyControlMode.SingleThreadLock)
        {
            Depth = algorithms.Length;
            Keys  = new SecureSymmetricKey[Depth];

            for (var i = 0; i < Depth; i++)
            {
                Keys[i] = SecureSymmetricKey.New(algorithms[i], derivationMode);
            }
        }
Exemple #2
0
 /// <summary>
 /// Decrypts the specified ciphertext.
 /// </summary>
 /// <param name="ciphertext">
 /// The ciphertext to decrypt.
 /// </param>
 /// <param name="key">
 /// The key derivation bits and algorithm specification used to transform the ciphertext.
 /// </param>
 /// <returns>
 /// The resulting plaintext object.
 /// </returns>
 /// <exception cref="SecurityException">
 /// An exception was raised during decryption or deserialization.
 /// </exception>
 public T Decrypt(Byte[] ciphertext, SecureSymmetricKey key)
 {
     try
     {
         using (var keyBuffer = key.DeriveKey())
         {
             return(Decrypt(ciphertext, keyBuffer, key.Algorithm));
         }
     }
     catch
     {
         throw new SecurityException("The decryption operation failed.");
     }
 }
Exemple #3
0
 /// <summary>
 /// Encrypts the specified plaintext object.
 /// </summary>
 /// <param name="plaintextObject">
 /// The plaintext object to encrypt.
 /// </param>
 /// <param name="key">
 /// The key derivation bits and algorithm specification used to transform the object.
 /// </param>
 /// <param name="initializationVector">
 /// An initialization vector with length greater than or equal to the block size for the specified cipher (extra bytes are
 /// ignored), or <see langword="null" /> to generate a random initialization vector.
 /// </param>
 /// <returns>
 /// The resulting ciphertext.
 /// </returns>
 /// <exception cref="SecurityException">
 /// An exception was raised during encryption or serialization.
 /// </exception>
 public Byte[] Encrypt(T plaintextObject, SecureSymmetricKey key, Byte[] initializationVector)
 {
     try
     {
         using (var keyBuffer = key.DeriveKey())
         {
             return(Encrypt(plaintextObject, keyBuffer, key.Algorithm, initializationVector));
         }
     }
     catch
     {
         throw new SecurityException("The encryption operation failed.");
     }
 }
        /// <summary>
        /// Creates a new instance of a <see cref="CascadingSymmetricKey" /> using the specified buffer.
        /// </summary>
        /// <param name="buffer">
        /// A binary representation of a <see cref="CascadingSymmetricKey" />.
        /// </param>
        /// <returns>
        /// A new instance of a <see cref="CascadingSymmetricKey" />.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// <paramref name="buffer" /> is invalid.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="buffer" /> is <see langword="null" />.
        /// </exception>
        public static CascadingSymmetricKey FromBuffer(SecureBuffer buffer)
        {
            buffer.RejectIf().IsNull(nameof(buffer)).OrIf(argument => argument.Length != SerializedLength, nameof(buffer), "The specified buffer is invalid.");

            try
            {
                var keys = (SecureSymmetricKey[])null;

                buffer.Access(pinnedBuffer =>
                {
                    // Interrogate the final 16 bits to determine the depth.
                    var keyLength = SecureSymmetricKey.SerializedLength;
                    var depth     = BitConverter.ToUInt16(pinnedBuffer, (SerializedLength - sizeof(UInt16)));
                    keys          = new SecureSymmetricKey[depth];

                    for (var i = 0; i < depth; i++)
                    {
                        using (var secureBuffer = new SecureBuffer(keyLength))
                        {
                            secureBuffer.Access(keyBuffer =>
                            {
                                // Copy out the key buffers.
                                Array.Copy(pinnedBuffer, (keyLength * i), keyBuffer, 0, keyLength);
                            });

                            keys[i] = SecureSymmetricKey.FromBuffer(secureBuffer);
                        }
                    }
                });

                return(new CascadingSymmetricKey(keys));
            }
            catch
            {
                throw new ArgumentException("The specified buffer is invalid.", nameof(buffer));
            }
        }
        /// <summary>
        /// Creates a new instance of a <see cref="SecureSymmetricKey" /> using the specified buffer.
        /// </summary>
        /// <param name="buffer">
        /// A binary representation of a <see cref="SecureSymmetricKey" />.
        /// </param>
        /// <returns>
        /// A new instance of a <see cref="SecureSymmetricKey" />.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// <paramref name="buffer" /> is invalid.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="buffer" /> is <see langword="null" />.
        /// </exception>
        public static SecureSymmetricKey FromBuffer(SecureBuffer buffer)
        {
            buffer.RejectIf().IsNull(nameof(buffer)).OrIf(argument => argument.Length != SerializedLength, nameof(buffer), "The specified buffer is invalid.");

            try
            {
                var result = (SecureSymmetricKey)null;

                buffer.Access(pinnedCiphertext =>
                {
                    using (var plaintextBuffer = new PinnedBuffer(SerializedPlaintextLength, true))
                    {
                        using (var cipher = BufferEncryptionAlgorithm.ToCipher(RandomnessProvider))
                        {
                            using (var plaintext = cipher.Decrypt(pinnedCiphertext, BufferEncryptionKey))
                            {
                                Array.Copy(plaintext, 0, plaintextBuffer, 0, SerializedPlaintextLength);
                            }
                        }

                        using (var keySource = new PinnedBuffer(KeySourceLengthInBytes, true))
                        {
                            Array.Copy(plaintextBuffer, KeySourceBufferIndex, keySource, 0, KeySourceLengthInBytes);
                            var algorithm      = (SymmetricAlgorithmSpecification)plaintextBuffer[AlgorithmBufferIndex];
                            var derivationMode = (SecureSymmetricKeyDerivationMode)plaintextBuffer[DerivationModeBufferIndex];
                            result             = new SecureSymmetricKey(algorithm, derivationMode, keySource);
                        }
                    }
                });

                return(result);
            }
            catch
            {
                throw new ArgumentException("The specified buffer is invalid.", nameof(buffer));
            }
        }
Exemple #6
0
 /// <summary>
 /// Encrypts the specified plaintext object.
 /// </summary>
 /// <param name="plaintextObject">
 /// The plaintext object to encrypt.
 /// </param>
 /// <param name="key">
 /// The key derivation bits and algorithm specification used to transform the object.
 /// </param>
 /// <returns>
 /// The resulting ciphertext.
 /// </returns>
 /// <exception cref="SecurityException">
 /// An exception was raised during encryption or serialization.
 /// </exception>
 public Byte[] Encrypt(T plaintextObject, SecureSymmetricKey key) => Encrypt(plaintextObject, key, null);