示例#1
0
 public WalletInfo(EncryptedDataContainer encryptedWalletData, string walletName, string[][] walletAddresses, int walletNum)
 {
     EncryptedWalletData = encryptedWalletData;
     WalletNum           = walletNum;
     WalletAddresses     = walletAddresses;
     WalletName          = walletName;
 }
        private void TestDecryptDoFinalArguments(EncryptedDataContainer edc)
        {
            PlainFileKey         pfk       = TestUtilities.ReadTestResource <PlainFileKey>(TestResources.plain_file_key);
            FileDecryptionCipher decCipher = Crypto.CreateFileDecryptionCipher(pfk);

            decCipher.DoFinal(edc);
        }
        //[TestMethod()]
        public void TestEnDecryption()
        {
            PlainFileKey generatedFK = Crypto.GenerateFileKey();

            byte[] plainFileBytes = Encoding.UTF8.GetBytes("Dinge die ich jetzt testen will.");

            // Encrypt text
            PlainDataContainer     plainDC   = new PlainDataContainer(plainFileBytes);
            FileEncryptionCipher   encCipher = Crypto.CreateFileEncryptionCipher(generatedFK);
            EncryptedDataContainer encryptedResult;

            using (MemoryStream ms = new MemoryStream()) {
                EncryptedDataContainer encryptedDC = encCipher.ProcessBytes(plainDC);
                ms.Write(encryptedDC.Content, 0, encryptedDC.Content.Length);
                encryptedDC = encCipher.DoFinal();
                ms.Write(encryptedDC.Content, 0, encryptedDC.Content.Length);
                encryptedResult = new EncryptedDataContainer(ms.ToArray(), encryptedDC.Tag);
            }
            generatedFK.Tag = Convert.ToBase64String(encryptedResult.Tag);

            // Decrypt text
            FileDecryptionCipher decCipher = Crypto.CreateFileDecryptionCipher(generatedFK);
            PlainDataContainer   decryptedResult;

            using (MemoryStream ms = new MemoryStream()) {
                PlainDataContainer decryptedDC = decCipher.ProcessBytes(new EncryptedDataContainer(encryptedResult.Content, null));
                ms.Write(decryptedDC.Content, 0, decryptedDC.Content.Length);
                decryptedDC = decCipher.DoFinal(new EncryptedDataContainer(null, Convert.FromBase64String(generatedFK.Tag)));
                ms.Write(decryptedDC.Content, 0, decryptedDC.Content.Length);
                decryptedResult = new PlainDataContainer(ms.ToArray());
            }

            System.Diagnostics.Debug.WriteLine("Result: " + Encoding.UTF8.GetString(decryptedResult.Content));
        }
        public void TestEncryptMultiBlock_Success()
        {
            PlainFileKey pfk = TestUtilities.ReadTestResource <PlainFileKey>(TestResources.plain_file_key);

            byte[] ft  = Convert.FromBase64String(pfk.Tag);
            byte[] pfc = Convert.FromBase64String(TestResources.plain_file);
            byte[] efc = Convert.FromBase64String(TestResources.enc_file);

            FileEncryptionCipher encCipher = Crypto.CreateFileEncryptionCipher(pfk);

            using (MemoryStream output = new MemoryStream()) {
                using (MemoryStream input = new MemoryStream(pfc)) {
                    byte[] buffer = new byte[16];
                    int    bytesRead;
                    while ((bytesRead = input.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        byte[] blockBytes = new byte[bytesRead];
                        Array.Copy(buffer, blockBytes, bytesRead);
                        EncryptedDataContainer currentEdc = encCipher.ProcessBytes(new PlainDataContainer(blockBytes));
                        output.Write(currentEdc.Content, 0, currentEdc.Content.Length);
                    }
                }
                EncryptedDataContainer testEdc = encCipher.DoFinal();
                output.Write(testEdc.Content, 0, testEdc.Content.Length);

                byte[] testFt  = testEdc.Tag;
                byte[] testEfc = output.ToArray();

                CollectionAssert.AreEqual(efc, testEfc, "File content does not match!");
                CollectionAssert.AreEqual(ft, testFt, "File tag does not match!");
            }
        }
示例#5
0
        /// <summary>
        /// Decrypt the cipher data with AES in Mode GCM
        /// </summary>
        /// <param name="key">Must have a length of 128, 192, or 256</param>
        /// <param name="encryptedDataContainer">Contains the cipher text, the nonce, the tag and the associatedData</param>
        /// <returns>Plain text</returns>
        public static byte[] Decrypt(byte[] key, EncryptedDataContainer encryptedDataContainer)
        {
            var plainText = new byte[encryptedDataContainer.CipherText.Length];

            var aes = new System.Security.Cryptography.AesGcm(key);

            aes.Decrypt(encryptedDataContainer.Nonce, encryptedDataContainer.CipherText, encryptedDataContainer.Tag, plainText, encryptedDataContainer.AssociatedData);

            return(plainText);
        }
        public void TestEncryptSingleBlock_DifferentContent()
        {
            PlainFileKey pfk = TestUtilities.ReadTestResource <PlainFileKey>(TestResources.plain_file_key);

            byte[] pfc = Convert.FromBase64String(TestResources.plain_file_modified);
            byte[] efc = Convert.FromBase64String(TestResources.enc_file);

            PlainDataContainer     testPdc = new PlainDataContainer(pfc);
            EncryptedDataContainer testEdc = TestEncryptSingleBlock(pfk, testPdc);

            CollectionAssert.AreNotEqual(efc, testEdc.Content, "File content does match!");
        }
        private PlainDataContainer TestDecryptSingleBlock(PlainFileKey pfk, EncryptedDataContainer edc)
        {
            FileDecryptionCipher decryptCipher = Crypto.CreateFileDecryptionCipher(pfk);

            using (MemoryStream ms = new MemoryStream()) {
                PlainDataContainer pdc = decryptCipher.ProcessBytes(new EncryptedDataContainer(edc.Content, null));
                ms.Write(pdc.Content, 0, pdc.Content.Length);
                pdc = decryptCipher.DoFinal(new EncryptedDataContainer(null, edc.Tag));
                ms.Write(pdc.Content, 0, pdc.Content.Length);
                return(new PlainDataContainer(ms.ToArray()));
            }
        }
        public void TestEncryptSingleBlock_DifferentTag()
        {
            PlainFileKey pfk = TestUtilities.ReadTestResource <PlainFileKey>(TestResources.plain_file_key_bad_tag);

            byte[] ft  = Convert.FromBase64String(pfk.Tag);
            byte[] pfc = Convert.FromBase64String(TestResources.plain_file);

            PlainDataContainer     testPdc = new PlainDataContainer(pfc);
            EncryptedDataContainer testEdc = TestEncryptSingleBlock(pfk, testPdc);

            CollectionAssert.AreNotEqual(ft, testEdc.Tag, "File tag does not match!");
        }
        private EncryptedDataContainer TestEncryptSingleBlock(PlainFileKey pfk, PlainDataContainer pdc)
        {
            FileEncryptionCipher encCipher = Crypto.CreateFileEncryptionCipher(pfk);

            using (MemoryStream output = new MemoryStream()) {
                EncryptedDataContainer currentEdc = encCipher.ProcessBytes(pdc);
                output.Write(currentEdc.Content, 0, currentEdc.Content.Length);
                currentEdc = encCipher.DoFinal();
                output.Write(currentEdc.Content, 0, currentEdc.Content.Length);
                return(new EncryptedDataContainer(output.ToArray(), currentEdc.Tag));
            }
        }
        private void EncryptedDownload(Uri downloadUri, PlainFileKey plainFileKey)
        {
            FileDecryptionCipher cipher;

            try {
                cipher = Crypto.Sdk.Crypto.CreateFileDecryptionCipher(plainFileKey);
            } catch (CryptoException ce) {
                string message = "Creation of decryption engine for encrypted download " + ActionId + " failed!";
                DracoonClient.Log.Debug(Logtag, message);
                throw new DracoonCryptoException(CryptoErrorMapper.ParseCause(ce), ce);
            }

            try {
                ProgressReportTimer = Stopwatch.StartNew();
                long downloadedByteCount = 0;
                while (downloadedByteCount < AssociatedNode.Size.GetValueOrDefault(0))
                {
                    byte[] chunk = DownloadChunk(downloadUri, downloadedByteCount, AssociatedNode.Size.GetValueOrDefault(0));
                    EncryptedDataContainer encryptedContainer = new EncryptedDataContainer(chunk, null);
                    PlainDataContainer     plainContainer     = cipher.ProcessBytes(encryptedContainer);
                    OutputStream.Write(plainContainer.Content, 0, plainContainer.Content.Length);
                    downloadedByteCount += chunk.Length;
                }

                byte[] encryptionTag = Convert.FromBase64String(plainFileKey.Tag);
                EncryptedDataContainer tagContainer   = new EncryptedDataContainer(null, encryptionTag);
                PlainDataContainer     finalContainer = cipher.DoFinal(tagContainer);
                OutputStream.Write(finalContainer.Content, 0, finalContainer.Content.Length);
                if (LastNotifiedProgressValue != downloadedByteCount)
                {
                    // Notify 100 percent progress
                    NotifyProgress(ActionId, downloadedByteCount, AssociatedNode.Size.GetValueOrDefault(0));
                }
            } catch (CryptoException ce) {
                const string message = "Decryption of file failed while downloading!";
                DracoonClient.Log.Debug(Logtag, message);
                throw new DracoonFileIOException(message, ce);
            } catch (IOException ioe) {
                if (IsInterrupted)
                {
                    throw new ThreadInterruptedException();
                }

                const string message = "Write to stream failed!";
                DracoonClient.Log.Debug(Logtag, message);
                throw new DracoonFileIOException(message, ioe);
            } finally {
                ProgressReportTimer.Stop();
            }
        }
        public void TestDecryptSingleBlock_Success()
        {
            PlainFileKey pfk = TestUtilities.ReadTestResource <PlainFileKey>(TestResources.plain_file_key);

            byte[] fileTag = Convert.FromBase64String(pfk.Tag);
            byte[] ef      = Convert.FromBase64String(TestResources.enc_file);
            byte[] pf      = Convert.FromBase64String(TestResources.plain_file);

            EncryptedDataContainer testEdc = new EncryptedDataContainer(ef, fileTag);
            PlainDataContainer     testPdc = TestDecryptSingleBlock(pfk, testEdc);

            System.Diagnostics.Debug.WriteLine(Convert.ToBase64String(testPdc.Content));
            System.Diagnostics.Debug.WriteLine(Convert.ToBase64String(pf));
            CollectionAssert.AreEqual(pf, testPdc.Content, "File content does not match!");
        }
        public void TestDecryptSingleBlock_ModifiedContent()
        {
            PlainFileKey pfk = TestUtilities.ReadTestResource <PlainFileKey>(TestResources.plain_file_key);

            byte[] ft  = Convert.FromBase64String(pfk.Tag);
            byte[] efc = Convert.FromBase64String(TestResources.enc_file_modified);
            EncryptedDataContainer testEdc = new EncryptedDataContainer(efc, ft);

            try {
                TestDecryptSingleBlock(pfk, testEdc);
            } catch (BadFileException) {
                return;
            }
            Assert.Fail();
        }
 /// <summary>
 /// Completes the decryption. After this method is called no further calls of
 /// <see cref="ProcessBytes(EncryptedDataContainer)"/> and
 /// <see cref="DoFinal(EncryptedDataContainer)"/> are possible.
 /// </summary>
 /// <param name="encryptedData">The data container with the previously calculated tag.</param>
 /// <returns>The data container with the decrypted bytes.</returns>
 /// <exception cref="Dracoon.Crypto.Sdk.CryptoException"/>
 /// <exception cref="Dracoon.Crypto.Sdk.BadFileException"/>
 /// <exception cref="System.ArgumentNullException"/>
 /// <exception cref="System.ArgumentException"/>
 public PlainDataContainer DoFinal(EncryptedDataContainer encryptedData)
 {
     if (encryptedData == null)
     {
         throw new ArgumentNullException("Data container cannot be null.");
     }
     if (encryptedData.Content != null)
     {
         throw new ArgumentException("Data container content cannot be null.");
     }
     if (encryptedData.Tag == null)
     {
         throw new ArgumentNullException("Data container tag must be null.");
     }
     return(new PlainDataContainer(Process(encryptedData.Tag, true)));
 }
 /// <summary>
 /// Decrypts some bytes.
 /// </summary>
 /// <param name="encryptedData">The data container with the bytes to decrypt.</param>
 /// <returns>The data container with the decrypted bytes.</returns>
 /// <exception cref="Dracoon.Crypto.Sdk.CryptoException"/>
 /// <exception cref="Dracoon.Crypto.Sdk.BadFileException"/>
 /// <exception cref="System.ArgumentNullException"/>
 /// <exception cref="System.ArgumentException"/>
 public PlainDataContainer ProcessBytes(EncryptedDataContainer encryptedData)
 {
     if (encryptedData == null)
     {
         throw new ArgumentNullException("Data container cannot be null.");
     }
     if (encryptedData.Content == null)
     {
         throw new ArgumentNullException("Data container content cannot be null.");
     }
     if (encryptedData.Tag != null)
     {
         throw new ArgumentException("Data container tag must be null.");
     }
     return(new PlainDataContainer(Process(encryptedData.Content, false)));
 }
        private void EncryptedUpload(ref PlainFileKey plainFileKey)
        {
            DracoonClient.Log.Debug(LogTag, "Uploading file [" + FileUploadRequest.Name + "] in encrypted proxied way.");
            FileEncryptionCipher cipher;

            try {
                cipher = Crypto.Sdk.Crypto.CreateFileEncryptionCipher(plainFileKey);
            } catch (CryptoException ce) {
                string message = "Creation of encryption engine for encrypted upload " + ActionId + " failed!";
                DracoonClient.Log.Debug(LogTag, message);
                throw new DracoonCryptoException(CryptoErrorMapper.ParseCause(ce));
            }

            try {
                long   uploadedByteCount = 0;
                byte[] buffer            = new byte[DracoonClient.HttpConfig.ChunkSize];
                int    bytesRead         = 0;
                while ((bytesRead = InputStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    EncryptedDataContainer encryptedContainer = EncryptChunk(cipher, bytesRead, buffer, false);
                    ProcessEncryptedChunk(new Uri(UploadToken.UploadUrl), encryptedContainer, uploadedByteCount, cipher, false);
                    uploadedByteCount += encryptedContainer.Content.Length;
                }

                EncryptedDataContainer finalEncryptedContainer = EncryptChunk(cipher, bytesRead, buffer, true);
                plainFileKey.Tag   = ProcessEncryptedChunk(new Uri(UploadToken.UploadUrl), finalEncryptedContainer, uploadedByteCount, cipher, true);
                uploadedByteCount += finalEncryptedContainer.Content.Length;
                if (LastNotifiedProgressValue != uploadedByteCount)
                {
                    // Notify 100 percent progress
                    NotifyProgress(ActionId, uploadedByteCount, OptionalFileSize);
                }
            } catch (IOException ioe) {
                if (IsInterrupted)
                {
                    throw new ThreadInterruptedException();
                }

                string message = "Read from stream failed!";
                DracoonClient.Log.Debug(LogTag, message);
                throw new DracoonFileIOException(message, ioe);
            } finally {
                ProgressReportTimer?.Stop();
            }
        }
        private string ProcessEncryptedChunk(Uri uploadUrl, EncryptedDataContainer encryptedContainer, long uploadedByteCount, FileEncryptionCipher cipher,
                                             bool isFinalBlock, int sendTry = 1)
        {
            ApiUploadChunkResult chunkResult =
                UploadChunkWebClient(uploadUrl, encryptedContainer.Content, uploadedByteCount, encryptedContainer.Content.Length);

            if (!FileHash.CompareFileHashes(chunkResult.Hash, encryptedContainer.Content, encryptedContainer.Content.Length))
            {
                if (sendTry <= 3)
                {
                    return(ProcessEncryptedChunk(uploadUrl, encryptedContainer, uploadedByteCount, cipher, isFinalBlock, sendTry + 1));
                }
                else
                {
                    throw new DracoonNetIOException("The uploaded chunk hash and local chunk hash are not equal!");
                }
            }

            return(isFinalBlock ? Convert.ToBase64String(encryptedContainer.Tag) : null);
        }
        private List <ApiS3FileUploadPart> EncryptedS3Upload(ref PlainFileKey plainFileKey)
        {
            DracoonClient.Log.Debug(LogTag, "Uploading file [" + FileUploadRequest.Name + "] via encrypted s3 direct upload.");
            FileEncryptionCipher cipher;

            try {
                cipher = Crypto.Sdk.Crypto.CreateFileEncryptionCipher(plainFileKey);
            } catch (CryptoException ce) {
                DracoonClient.Log.Debug(LogTag, "Creation of encryption engine for encrypted upload " + ActionId + " failed!");
                throw new DracoonCryptoException(CryptoErrorMapper.ParseCause(ce));
            }

            try {
                int    chunkSize = DefineS3ChunkSize();
                int    s3UrlBatchSize = DefineS3BatchSize(chunkSize);
                long   uploadedByteCount = 0;
                byte[] buffer = new byte[chunkSize];
                int    bytesRead, offset = 0;

                while ((bytesRead = InputStream.Read(buffer, offset, buffer.Length - offset)) >= 0)
                {
                    int    nextByte = InputStream.ReadByte(); // Check if further bytes are available
                    byte[] chunk;

                    EncryptedDataContainer container = EncryptChunk(cipher, bytesRead + offset, buffer, false);
                    if (nextByte == -1)
                    {
                        // It is the last block
                        EncryptedDataContainer finalContainer = EncryptChunk(cipher, bytesRead + offset, buffer, true);
                        plainFileKey.Tag = Convert.ToBase64String(finalContainer.Tag);
                        chunk            = new byte[container.Content.Length + finalContainer.Content.Length];
                        Buffer.BlockCopy(finalContainer.Content, 0, chunk, container.Content.Length, finalContainer.Content.Length);
                    }
                    else
                    {
                        chunk = new byte[container.Content.Length];
                    }

                    Buffer.BlockCopy(container.Content, 0, chunk, 0, container.Content.Length);

                    if (chunk.Length < chunkSize)
                    {
                        S3Urls = RequestS3Urls(S3Parts.Count + 1, 1, chunk.Length);
                    }
                    else if (S3Urls.Count == 0)
                    {
                        S3Urls = RequestS3Urls(S3Parts.Count + 1, s3UrlBatchSize, chunkSize);
                    }

                    string partETag = UploadS3ChunkWebClient(S3Urls.Dequeue(), chunk, uploadedByteCount);
                    S3Parts.Add(new ApiS3FileUploadPart()
                    {
                        PartEtag   = partETag,
                        PartNumber = S3Parts.Count + 1
                    });
                    uploadedByteCount += chunk.Length;

                    if (nextByte != -1)
                    {
                        // Do it every time if the current block isn't the last
                        Buffer.SetByte(buffer, 0, (byte)nextByte);
                        offset = 1;
                    }
                    else
                    {
                        break;
                    }
                }

                if (LastNotifiedProgressValue != uploadedByteCount)
                {
                    // Notify 100 percent progress
                    NotifyProgress(ActionId, uploadedByteCount, OptionalFileSize);
                }

                return(S3Parts);
            } catch (IOException ioe) {
                if (IsInterrupted)
                {
                    throw new ThreadInterruptedException();
                }

                string message = "Read from stream failed!";
                DracoonClient.Log.Debug(LogTag, message);
                throw new DracoonFileIOException(message, ioe);
            } finally {
                ProgressReportTimer?.Stop();
            }
        }