예제 #1
0
        public void Encrypt(ReadOnlySpan <byte> nonce, ReadOnlySpan <byte> source,
                            Span <byte> destination, Span <byte> tag, ReadOnlySpan <byte> associatedData = default)
        {
            var input = ArrayPool <byte> .Shared.Rent(source.Length);

            var output = ArrayPool <byte> .Shared.Rent(destination.Length + tag.Length);

            try
            {
                _engine = new BufferedAeadBlockCipher(new GcmBlockCipher(_aes));
                _engine.Init(true, new AeadParameters(_key, 128, nonce.ToArray(), associatedData.ToArray()));

                source.CopyTo(input);

                _engine.DoFinal(input, 0, source.Length, output, 0);

                output.AsSpan(0, destination.Length).CopyTo(destination);
                output.AsSpan(destination.Length, tag.Length).CopyTo(tag);
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(input);

                ArrayPool <byte> .Shared.Return(output);
            }
        }
예제 #2
0
        public void Decrypt(ReadOnlySpan <byte> nonce, ReadOnlySpan <byte> source, ReadOnlySpan <byte> tag,
                            Span <byte> destination, ReadOnlySpan <byte> associatedData = default)
        {
            var input = ArrayPool <byte> .Shared.Rent(source.Length + tag.Length);

            var output = ArrayPool <byte> .Shared.Rent(destination.Length);

            try
            {
                _engine.Init(false, new AeadParameters(_key, 128, nonce.ToArray(), associatedData.ToArray()));

                source.CopyTo(input);
                tag.CopyTo(input.AsSpan(source.Length));

                _engine.DoFinal(input, 0, source.Length + tag.Length, output, 0);

                output.AsSpan(0, destination.Length).CopyTo(destination);
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(input);

                ArrayPool <byte> .Shared.Return(output);
            }
        }
        /// <summary>
        /// Create a buffered cipher to encrypt or decrypt a stream as it is being read
        /// </summary>
        /// <param name="forEncryption">forEncryption if true the cipher is initialised for encryption, if false for decryption</param>
        /// <param name="key">Key to be used for encryption</param>
        /// <param name="nonce">Nonce to be used for encryption</param>
        /// <param name="tagSize">Tag size in bits for the tag appended in the end of the stream</param>
        /// <param name="associatedText">Additional associated data</param>
        /// <returns></returns>
        internal static IBufferedCipher CreateCipher(bool forEncryption, byte[] key, int tagSize, byte[] nonce, byte[] associatedText)
        {
            var aesEngine       = new AesEngine();
            var blockCipher     = new GcmBlockCipher(aesEngine);
            var aeadBlockCipher = new BufferedAeadBlockCipher(blockCipher);
            var parameters      = new AeadParameters(new KeyParameter(key), tagSize, nonce, associatedText);

            aeadBlockCipher.Init(forEncryption, parameters);
            return(aeadBlockCipher);
        }