예제 #1
0
        private static async Task DecryptContentAsync(Stream source, Stream destination, int recordSize, byte[] contentEncryptionKeyInfoParameterHash, byte[] nonceInfoParameterHash)
        {
            using (Aes128GcmCipher aes128GcmCipher = new Aes128GcmCipher(contentEncryptionKeyInfoParameterHash, nonceInfoParameterHash))
            {
                int    maxPlainTextLength = recordSize - RECORD_ENCRYPTION_OVERHEAD_SIZE - RECORD_DELIMITER_SIZE;
                byte[] plainTextBuffer    = _arrayPool.Rent(maxPlainTextLength + RECORD_DELIMITER_SIZE);
                byte[] cipherTextBuffer   = _arrayPool.Rent(recordSize);

                try
                {
                    int recordDelimiterIndex = 0;

                    ulong recordSequenceNumber = 0;
                    do
                    {
                        int cipherTextLength = await source.ReadAsync(cipherTextBuffer, 0, recordSize).ConfigureAwait(false);

                        if (cipherTextLength == 0)
                        {
                            ThrowInvalidOrderOrMissingRecordException();
                        }

                        int plainTextLength = aes128GcmCipher.Decrypt(cipherTextBuffer, cipherTextLength, plainTextBuffer, recordSequenceNumber++);
                        recordDelimiterIndex = GetRecordDelimiterIndex(plainTextBuffer, plainTextLength, maxPlainTextLength);

                        if ((plainTextBuffer[recordDelimiterIndex] == LAST_RECORD_DELIMITER) && (source.ReadByte() != -1))
                        {
                            ThrowInvalidOrderOrMissingRecordException();
                        }

                        await destination.WriteAsync(plainTextBuffer, 0, recordDelimiterIndex).ConfigureAwait(false);
                    }while (plainTextBuffer[recordDelimiterIndex] != LAST_RECORD_DELIMITER);
                }
                finally
                {
                    _arrayPool.Return(plainTextBuffer, true);
                    _arrayPool.Return(cipherTextBuffer, true);
                }
            }
        }
예제 #2
0
        private static async Task EncryptContentAsync(Stream source, Stream destination, int recordSize, byte[] contentEncryptionKeyInfoParameterHash, byte[] nonceInfoParameterHash)
        {
            using (Aes128GcmCipher aes128GcmCipher = new Aes128GcmCipher(contentEncryptionKeyInfoParameterHash, nonceInfoParameterHash))
            {
                int    maxPlainTextLength = recordSize - RECORD_ENCRYPTION_OVERHEAD_SIZE - RECORD_DELIMITER_SIZE;
                byte[] plainTextBuffer    = _arrayPool.Rent(maxPlainTextLength + RECORD_DELIMITER_SIZE);
                byte[] cipherTextBuffer   = _arrayPool.Rent(recordSize);

                try
                {
                    int plainTextLength;
                    int?peekedPlainTextByte = null;

                    ulong recordSequenceNumber = 0;
                    do
                    {
                        plainTextLength = await GetPlainTextAsync(source, plainTextBuffer, maxPlainTextLength, (byte?)peekedPlainTextByte).ConfigureAwait(false);

                        if (plainTextBuffer[plainTextLength - 1] != LAST_RECORD_DELIMITER)
                        {
                            peekedPlainTextByte = source.ReadByte();
                            if (peekedPlainTextByte == -1)
                            {
                                plainTextBuffer[plainTextLength - 1] = LAST_RECORD_DELIMITER;
                            }
                        }

                        int cipherTextLength = aes128GcmCipher.Encrypt(plainTextBuffer, plainTextLength, cipherTextBuffer, recordSequenceNumber++);

                        await destination.WriteAsync(cipherTextBuffer, 0, cipherTextLength).ConfigureAwait(false);
                    }while (plainTextBuffer[plainTextLength - 1] != LAST_RECORD_DELIMITER);
                }
                finally
                {
                    _arrayPool.Return(plainTextBuffer, true);
                    _arrayPool.Return(cipherTextBuffer, true);
                }
            }
        }