Пример #1
0
        public static JsonWebEncryptedToken Parse(string token, string privateKey)
        {
            byte[]           claimSet = null;
            EncryptedPayload payload  = null;

            try
            {
                payload = EncryptedPayload.Parse(token);

                byte[] masterKey = null;
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                {
                    rsa.FromXmlString(privateKey);
                    masterKey = rsa.Decrypt(payload.EncryptedMasterKey, true);
                }

                byte[] additionalAuthenticatedData = payload.ToAdditionalAuthenticatedData();
                using (AuthenticatedAesCng aes = new AuthenticatedAesCng())
                {
                    aes.CngMode           = CngChainingMode.Gcm;
                    aes.Key               = masterKey;
                    aes.IV                = payload.InitializationVector;
                    aes.AuthenticatedData = additionalAuthenticatedData;
                    aes.Tag               = payload.Tag;

                    using (MemoryStream ms = new MemoryStream())
                    {
                        using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(),
                                                                  CryptoStreamMode.Write))
                        {
                            byte[] cipherText = payload.CipherText;
                            cs.Write(cipherText, 0, cipherText.Length);
                            cs.FlushFinalBlock();

                            claimSet = ms.ToArray();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new SecurityException("Invalid Token", ex);
            }

            var jwt = JsonConvert.DeserializeObject <JsonWebEncryptedToken>(payload.Header);

            jwt.AsymmetricKey = privateKey;
            jwt.claims        = JsonConvert.DeserializeObject
                                <Dictionary <string, string> >(Encoding.UTF8.GetString(claimSet));

            TimeSpan ts = DateTime.UtcNow - epochStart;

            if (jwt.ExpiresOn < Convert.ToUInt64(ts.TotalSeconds))
            {
                throw new SecurityException("Token has expired");
            }

            return(jwt);
        }
Пример #2
0
        public void AuthenticatedAesCngGcmMultiRoundTripTest()
        {
            byte[] plaintext          = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };
            byte[] plaintext2         = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };
            byte[] expectedCiphertext = new byte[]
            {
                0x54, 0x2d, 0x26, 0x15, 0x9c, 0xb3, 0x6e, 0x21, 0xd2, 0x58, 0xcf, 0x9c, 0x6e, 0xce, 0xfb, 0x5f,
                0x8c, 0x2a, 0xb8, 0x22, 0x4d, 0x6d, 0xd0, 0x02, 0x76, 0xd2, 0xab, 0x22, 0xa2, 0xd6, 0xee, 0x5b
            };
            byte[] expectedTag = new byte[] { 0xc1, 0x34, 0x38, 0x0b, 0xc3, 0x87, 0x7c, 0xf5, 0x2f, 0x3b, 0xa9, 0xfe, 0x3c, 0x69, 0x4b, 0x9f };
            byte[] key         = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };
            byte[] iv          = new byte[] { 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };

            using (AuthenticatedAesCng gcm = new AuthenticatedAesCng())
            {
                gcm.CngMode = CngChainingMode.Gcm;
                gcm.Key     = key;
                gcm.IV      = iv;
                gcm.Tag     = expectedTag;

                // Encrypt
                byte[] ciphertext = null;
                using (MemoryStream ms = new MemoryStream())
                    using (IAuthenticatedCryptoTransform encryptor = gcm.CreateAuthenticatedEncryptor())
                        using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                        {
                            // Push through two blocks and call final to get the tag.
                            cs.Write(plaintext, 0, plaintext.Length);
                            cs.Write(plaintext2, 0, plaintext2.Length);
                            cs.FlushFinalBlock();

                            ciphertext = ms.ToArray();

                            // Check if the ciphertext and tag are what are expected.
                            Assert.IsTrue(Util.CompareBytes(expectedCiphertext, ciphertext));
                            Assert.IsTrue(Util.CompareBytes(expectedTag, encryptor.GetTag()));
                        }

                // Decrypt
                using (MemoryStream ms = new MemoryStream())
                    using (ICryptoTransform decryptor = gcm.CreateDecryptor())
                        using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
                        {
                            cs.Write(ciphertext, 0, ciphertext.Length / 2);
                            cs.Write(ciphertext, ciphertext.Length / 2, ciphertext.Length / 2);

                            cs.FlushFinalBlock();

                            byte[] decrypted = ms.ToArray();

                            // Compare the decrypted text to the initial ciphertext.
                            byte[] fullPlaintext = new byte[plaintext.Length + plaintext2.Length];
                            Array.Copy(plaintext, 0, fullPlaintext, 0, plaintext.Length);
                            Array.Copy(plaintext2, 0, fullPlaintext, plaintext.Length, plaintext2.Length);
                            Assert.IsTrue(Util.CompareBytes(fullPlaintext, decrypted));
                        }
            }
        }
        private void RunTestVector(GcmTestVector test)
        {
            // Encrypt the input
            byte[] ciphertext = null;
            using (AuthenticatedAesCng gcm = new AuthenticatedAesCng())
            {
                gcm.CngMode           = CngChainingMode.Gcm;
                gcm.Key               = test.Key;
                gcm.IV                = test.IVBytes;
                gcm.AuthenticatedData = test.AuthenticationData;

                using (MemoryStream ms = new MemoryStream())
                    using (IAuthenticatedCryptoTransform encryptor = gcm.CreateAuthenticatedEncryptor())
                        using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                        {
                            if (test.Plaintext != null)
                            {
                                cs.Write(test.Plaintext, 0, test.Plaintext.Length);
                            }

                            cs.FlushFinalBlock();
                            ciphertext = ms.ToArray();

                            // Verify the produced tag is what we expected it to be
                            Assert.IsTrue(Util.CompareBytes(test.Tag, encryptor.GetTag()));
                        }
            }

            if (test.Ciphertext != null)
            {
                // Verify the ciphertext is what we expected it to be
                Assert.IsTrue(Util.CompareBytes(test.Ciphertext, ciphertext));

                // Round trip the data
                using (AuthenticatedAesCng gcm = new AuthenticatedAesCng())
                {
                    gcm.CngMode           = CngChainingMode.Gcm;
                    gcm.Key               = test.Key;
                    gcm.IV                = test.IVBytes;
                    gcm.AuthenticatedData = test.AuthenticationData;
                    gcm.Tag               = test.Tag;

                    using (MemoryStream ms = new MemoryStream())
                        using (CryptoStream cs = new CryptoStream(ms, gcm.CreateDecryptor(), CryptoStreamMode.Write))
                        {
                            cs.Write(test.Ciphertext, 0, test.Ciphertext.Length);
                            cs.FlushFinalBlock();

                            byte[] plaintext = ms.ToArray();
                            Assert.IsTrue(Util.CompareBytes(test.Plaintext, plaintext));
                        }
                }
            }
        }
Пример #4
0
        public byte[] Decrypt(byte[] EncryptedData, byte[] Tag, byte[] PacketHead, long PacketID)
        {
            byte[] RetVar;
            using (AuthenticatedAesCng aes = new AuthenticatedAesCng())
            {
                aes.CngMode = CngChainingMode.Gcm;
                aes.Key     = DecryptionKey;

                //------------- Build Nonce -------------
                byte[] nonce = new byte[12];
                Array.Copy(DecryptNonceHash, nonce, 4);
                //Encryption flag probably
                Array.Copy(new byte[] { 0x00, 0x01 }, 0, nonce, 4, 2);
                //Little Endian Packet ID to be send
                //Array.Copy(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, 0, nonce, 6, 6);
                Array.Copy(BitConverter.GetBytes(PacketID).Reverse().ToArray(), 2, nonce, 6, 6);

                aes.IV = nonce;

                //------------- Build Associated Data -------------
                byte[] associatedData = new byte[13]; // { 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xFE, 0xFD, 0x00, 0x18 };
                //Encryption flag probably
                Array.Copy(new byte[] { 0x00, 0x01 }, associatedData, 2);
                //Little Endian Packet ID to be send
                Array.Copy(BitConverter.GetBytes(PacketID).Reverse().ToArray(), 2, associatedData, 2, 6);
                //Packet header
                //Array.Copy(new byte[] { 0x16, 0xFE, 0xFD }, 0, associatedData, 8, 3);
                Array.Copy(PacketHead, 0, associatedData, 8, 3);
                //data length
                short EncryptedDataLen = (short)EncryptedData.Length;
                Array.Copy(BitConverter.GetBytes(EncryptedDataLen).Reverse().ToArray(), 0, associatedData, 11, 2);
                //Array.Copy(new byte[] { 0x00, 0x18 }, 0, associatedData, 11, 2);

                aes.AuthenticatedData = associatedData;

                aes.Tag = Tag;

                using (MemoryStream ms = new MemoryStream())

                    using (var decryptor = aes.CreateDecryptor())

                        using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))

                        {
                            cs.Write(EncryptedData, 0, EncryptedData.Length);
                            cs.FlushFinalBlock();
                            RetVar = ms.ToArray();
                        }
            }

            return(RetVar);
        }
Пример #5
0
        public static byte[] Decrypt(byte[] record, byte[] key)
        {
            if (key.Length != KEY_SIZE)
            {
                throw new ArgumentOutOfRangeException(nameof(key), "Invalid key size.");
            }

            //check version
            if (record[0] != VERSION)
            {
                var offset = 1;
                var nonce  = new byte[NONCE_SIZE];
                Buffer.BlockCopy(record, 1, nonce, 0, NONCE_SIZE);

                offset += NONCE_SIZE;
                var tag = new byte[TAG_SIZE];
                Buffer.BlockCopy(record, offset, tag, 0, TAG_SIZE);

                offset += TAG_SIZE;
                var cipherText = new byte[record.Length - HEADER_LENGTH];
                Buffer.BlockCopy(record, offset, cipherText, 0, record.Length - HEADER_LENGTH);

                using (var aes = new AuthenticatedAesCng())
                {
                    aes.CngMode = CngChainingMode.Gcm;
                    aes.KeySize = KEY_SIZE * 8; //bytes to bits
                    aes.Key     = key;
                    aes.IV      = nonce;
                    aes.Tag     = tag;

                    using (var ms = new MemoryStream())
                        using (var encryptor = aes.CreateDecryptor())
                            using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                            {
                                cs.Write(cipherText, 0, cipherText.Length);
                                cs.FlushFinalBlock();
                                return(ms.ToArray());
                            }
                }
            }
            else
            {
                //unsupported data versions
                throw new CryptographicException("Unsupported encrypted format.");
            }
        }
Пример #6
0
        public static byte[] Decrypt(byte[] record, byte[] key)
        {
            if (key.Length != KEY_SIZE)
            {
                throw new ArgumentOutOfRangeException("key", "Invalid key size.");
            }

            //check version
            if (record[0] != VERSION)
            {
                var offset = 1;
                var nonce = new byte[NONCE_SIZE];
                Buffer.BlockCopy(record, 1, nonce, 0, NONCE_SIZE);

                offset += NONCE_SIZE;
                var tag = new byte[TAG_SIZE];
                Buffer.BlockCopy(record, offset, tag, 0, TAG_SIZE);

                offset += TAG_SIZE;
                var cipherText = new byte[record.Length - HEADER_LENGTH];
                Buffer.BlockCopy(record, offset, cipherText, 0, record.Length - HEADER_LENGTH);

                using (var aes = new AuthenticatedAesCng())
                {
                    aes.CngMode = CngChainingMode.Gcm;
                    aes.KeySize = KEY_SIZE * 8; //bytes to bits
                    aes.Key = key;
                    aes.IV = nonce;
                    aes.Tag = tag;

                    using (var ms = new MemoryStream())
                    using (var encryptor = aes.CreateDecryptor())
                    using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        cs.Write(cipherText, 0, cipherText.Length);
                        cs.FlushFinalBlock();
                        return ms.ToArray();
                    }
                }
            }
            else
            {
                //unsupported data versions
                throw new CryptographicException("Unsupported encrypted format.");
            }
        }
        public static string DecryptString(string str)
        {
            if (String.IsNullOrEmpty(str))
            {
                throw new ArgumentNullException("decryption string invalid");
            }

            using (AuthenticatedAesCng aes = new AuthenticatedAesCng())
            {
                byte[] encrypted = Convert.FromBase64String(str);               // Convert string to bytes.
                aes.Key               = GetEncryptionKey();                     // Retrieve Key.
                aes.IV                = GetIV(encrypted);                       // Parse IV from encrypted text.
                aes.Tag               = GetTag(encrypted);                      // Parse Tag from encrypted text.
                encrypted             = RemoveTagAndIV(encrypted);              // Remove Tag and IV for proper decryption.
                aes.CngMode           = CngChainingMode.Gcm;                    // Set Cryptographic Mode.
                aes.AuthenticatedData = GetAdditionalAuthenticationData();      // Set Authentication Data.

                using (MemoryStream memoryStream = new MemoryStream())
                    using (ICryptoTransform decryptor = aes.CreateDecryptor())
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Write))
                        {
                            // Decrypt through stream.
                            cryptoStream.Write(encrypted, 0, encrypted.Length);

                            // If the authentication tag does not validate, this call will throw a CryptographicException.
                            try
                            {
                                cryptoStream.FlushFinalBlock();
                            }
                            catch (CryptographicException cryptoException)
                            {
                            }
                            catch (NotSupportedException notSupportedException)
                            {
                            }

                            // Remove from stream and convert to string.
                            byte[] decrypted = memoryStream.ToArray();
                            return(Encoding.UTF8.GetString(decrypted));
                        }
            }
        }
Пример #8
0
        public byte[] Decrypt(byte[] key, byte[] encryptedText)
        {
            using (var authAesCng = new AuthenticatedAesCng())
            {
                authAesCng.CngMode = CngChainingMode.Gcm;

                authAesCng.Key = key;
                authAesCng.IV = GetIV(encryptedText);
                authAesCng.Tag = GetTag(encryptedText);
                var cipherText = GetCipherText(encryptedText);
                using (var stream = new MemoryStream())
                using (var encryptor = authAesCng.CreateDecryptor())
                using (var cryptoStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(cipherText, 0, cipherText.Length);
                    cryptoStream.FlushFinalBlock();

                    return stream.ToArray();
                }
            }
        }
Пример #9
0
        public void AuthenticatedAesCngChainingTest()
        {
            byte[] plaintext         = new byte[20 * 1024];
            byte[] iv                = new byte[12];
            byte[] authenticatedData = new byte[1024];

            using (RNGCng rng = new RNGCng())
            {
                rng.GetBytes(plaintext);
                rng.GetBytes(iv);
                rng.GetBytes(authenticatedData);
            }

            foreach (CngChainingMode chainingMode in new CngChainingMode[] { CngChainingMode.Ccm, CngChainingMode.Gcm })
            {
                using (AuthenticatedAesCng aes = new AuthenticatedAesCng())
                {
                    aes.AuthenticatedData = authenticatedData;
                    aes.CngMode           = chainingMode;
                    aes.IV = iv;

                    // Encrypt the whole block of data at once
                    byte[] wholeCiphertext = null;
                    byte[] wholeTag        = null;
                    using (IAuthenticatedCryptoTransform encryptor = aes.CreateAuthenticatedEncryptor())
                    {
                        wholeCiphertext = encryptor.TransformFinalBlock(plaintext, 0, plaintext.Length);
                        wholeTag        = encryptor.GetTag();
                    }

                    // Encrypt it in chunks
                    byte[] blockCiphertext = null;
                    byte[] blockTag        = null;
                    using (MemoryStream ms = new MemoryStream())
                        using (IAuthenticatedCryptoTransform encryptor = aes.CreateAuthenticatedEncryptor())
                            using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                            {
                                int chunkSize = 128;
                                for (int offset = 0; offset < plaintext.Length; offset += chunkSize)
                                {
                                    cs.Write(plaintext, offset, chunkSize);
                                }
                                cs.FlushFinalBlock();

                                blockCiphertext = ms.ToArray();
                                blockTag        = encryptor.GetTag();
                            }

                    // Make sure we got the same results in both cases
                    Assert.IsTrue(Util.CompareBytes(wholeCiphertext, blockCiphertext));
                    Assert.IsTrue(Util.CompareBytes(wholeTag, blockTag));

                    aes.Tag = wholeTag;

                    // Decrypt the whole block of data at once
                    using (ICryptoTransform decryptor = aes.CreateDecryptor())
                    {
                        byte[] wholePlaintext = decryptor.TransformFinalBlock(wholeCiphertext, 0, wholeCiphertext.Length);
                        Assert.IsTrue(Util.CompareBytes(plaintext, wholePlaintext));
                    }

                    // Decrypt the data in chunks
                    using (MemoryStream ms = new MemoryStream())
                        using (ICryptoTransform decryptor = aes.CreateDecryptor())
                            using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
                            {
                                int chunkSize = 128;
                                for (int offset = 0; offset < blockCiphertext.Length; offset += chunkSize)
                                {
                                    cs.Write(blockCiphertext, offset, chunkSize);
                                }
                                cs.FlushFinalBlock();

                                byte[] blockPlaintext = ms.ToArray();
                                Assert.IsTrue(Util.CompareBytes(plaintext, blockPlaintext));
                            }
                }
            }
        }
Пример #10
0
        /// <summary>
        ///     Perform a round trip test given input and the expected output
        /// </summary>
        private void AuthenticatedAesCngRoundTripTest(RoundTripTestData testData)
        {
            using (AuthenticatedAesCng aes = new AuthenticatedAesCng())
            {
                aes.CngMode = testData.ChainingMode;

                if (testData.Key != null)
                {
                    aes.Key = testData.Key;
                }

                if (testData.IV != null)
                {
                    aes.IV = testData.IV;
                }

                if (testData.AuthenticationData != null)
                {
                    aes.AuthenticatedData = testData.AuthenticationData;
                }

                if (testData.ExpectedTag != null)
                {
                    aes.Tag = testData.ExpectedTag;
                }

                // Encrypt
                byte[] ciphertext = null;
                byte[] tag        = null;
                using (MemoryStream ms = new MemoryStream())
                    using (IAuthenticatedCryptoTransform encryptor = aes.CreateAuthenticatedEncryptor())
                        using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                        {
                            cs.Write(testData.Plaintext, 0, testData.Plaintext.Length);
                            cs.FlushFinalBlock();

                            tag        = encryptor.GetTag();
                            ciphertext = ms.ToArray();

                            // Check if the ciphertext and tag are what are expected.
                            if (testData.ExpectedCiphertext != null)
                            {
                                Assert.IsTrue(Util.CompareBytes(testData.ExpectedCiphertext, ciphertext));
                            }

                            if (testData.ExpectedTag != null)
                            {
                                Assert.IsTrue(Util.CompareBytes(testData.ExpectedTag, tag));
                            }
                        }

                if (testData.ExpectedTag == null)
                {
                    aes.Tag = tag;
                }

                // Decrypt
                using (MemoryStream ms = new MemoryStream())
                    using (ICryptoTransform decryptor = aes.CreateDecryptor())
                        using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
                        {
                            cs.Write(ciphertext, 0, ciphertext.Length);
                            cs.FlushFinalBlock();

                            // Compare the decrypted text to the initial ciphertext.
                            byte[] decrypted = ms.ToArray();
                            Assert.IsTrue(Util.CompareBytes(testData.Plaintext, decrypted));
                        }
            }
        }
Пример #11
0
        public byte[] Decrypt(byte[] cipherBytes, int AddtnlAuthDataLength)
        {
            if (cipherBytes == null)
                return null;

            byte[] tag = new byte[TagBitSize / 8];

            try
            {

                using (AuthenticatedAesCng aes = new AuthenticatedAesCng())
                {
                    using (var cipherReader = new BinaryReader(new MemoryStream(cipherBytes)))
                    {
                        aes.CngMode = CngChainingMode.Gcm;
                        aes.Key = aesKey;
                        //Read Additional Authenticated Data (AddtnlAuthData)
                        aes.AuthenticatedData = cipherReader.ReadBytes(AddtnlAuthDataLength);
                        aes.IV = cipherReader.ReadBytes(IVBitSize / 8);
                        // Tag lives at the end and it small, array copy it over
                        Array.Copy(cipherBytes, cipherBytes.Length - (TagBitSize / 8), tag, 0, (TagBitSize / 8));
                        aes.Tag = tag;
                    }

                    using (var ms = new MemoryStream())
                    using (var cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        int startOffset = AddtnlAuthDataLength + (IVBitSize / 8);
                        var length = cipherBytes.Length - AddtnlAuthDataLength - (IVBitSize / 8) - (TagBitSize / 8);

                        cs.Write(cipherBytes, startOffset, length);

                        // If the authentication tag does not match, we'll fail here with a
                        // CryptographicException, and the ciphertext will not be decrypted.
                        cs.FlushFinalBlock();

                        return ms.ToArray();
                    }
                }
            }

            catch (Exception ex)
            {
                //Logger.Exception(ex);
                if (ex is ArgumentException ||
                    ex is CryptographicException ||
                    ex is OverflowException)
                {
                    return null; // this is null here
                }
                else
                {
                    throw;
                }
            }
        }
Пример #12
0
        private byte[] DecryptBuffer(byte[] encryptedInput, byte[] nonce, byte[] gcmtag, int keyinfo)
        {
            byte[] result;

            using (var authenticatedAesCng = new AuthenticatedAesCng())
            {
                authenticatedAesCng.CngMode = CngChainingMode.Gcm;
                if (keyinfo == 1)
                {
                    authenticatedAesCng.Key = this._key;
                }
                else if (keyinfo == 2)
                {
                    authenticatedAesCng.Key = this._altKey;
                }
                authenticatedAesCng.IV  = nonce;
                authenticatedAesCng.Tag = gcmtag;
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (CryptoStream cryptoStream = new CryptoStream(memoryStream, authenticatedAesCng.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cryptoStream.Write(encryptedInput, 0, encryptedInput.Length);
                        cryptoStream.FlushFinalBlock();
                        result = memoryStream.ToArray();
                    }
                }
            }
            return(result);
        }
Пример #13
0
        public static Some<Tuple<string, long>> DecryptFile(string dstDir, string filename, byte[] key)
        {
            if (!File.Exists(filename)) return ErrorValues[ErrorType.FileNoExist];

            using (var inputFile = File.OpenRead(filename))
            {
                var outerBuffer = new byte[TagStartPos];
                if (inputFile.Read(outerBuffer, 0, outerBuffer.Length) != outerBuffer.Length)
                {
                    return ErrorValues[ErrorType.NotAnEncryptedFile];
                }

                if (!outerBuffer.Take(OuterMagicHeader.Count).SequenceEqual(OuterMagicHeader))
                {
                    return ErrorValues[ErrorType.MagicBytesMismatch];
                }

                var tagLength = BitConverter.ToInt32(outerBuffer, OuterMagicHeader.Count);
                var ivLength = BitConverter.ToInt32(outerBuffer, OuterMagicHeader.Count + sizeof(Int32));

                using (var aes = new AuthenticatedAesCng())
                {
                    outerBuffer = new byte[tagLength + ivLength];
                    if (inputFile.Read(outerBuffer, 0, outerBuffer.Length) != outerBuffer.Length)
                    {
                        return ErrorValues[ErrorType.NotAnEncryptedFile];
                    }

                    aes.CngMode = CngChainingMode.Gcm;
                    aes.Key = key;
                    aes.Tag = outerBuffer.Take(tagLength).ToArray();
                    aes.IV = outerBuffer.Skip(tagLength).Take(ivLength).ToArray();

                    using (var dec = aes.CreateDecryptor())
                    using (var cryptoStream = new CryptoStream(inputFile, dec, CryptoStreamMode.Read))
                    {
                        var buf = new byte[MagicHeader.Count + sizeof(Int32)];
                        if (cryptoStream.Read(buf, 0, buf.Length) != buf.Length)
                        {
                            return ErrorValues[ErrorType.CorruptFile];
                        }

                        if (!buf.Take(MagicHeader.Count).SequenceEqual(MagicHeader))
                        {
                            return ErrorValues[ErrorType.MagicBytesMismatch];
                        }

                        var nameLength = BitConverter.ToInt32(buf, MagicHeader.Count);
                        buf = new byte[nameLength];
                        if (cryptoStream.Read(buf, 0, buf.Length) != buf.Length)
                        {
                            return ErrorValues[ErrorType.CorruptFile];
                        }
                        var fileName = Encoding.UTF8.GetString(buf, 0, buf.Length);

                        var outputFileName = Path.Combine(dstDir, fileName);
                        var outputDir = Path.GetDirectoryName(outputFileName);

                        if (string.IsNullOrWhiteSpace(outputDir)) return ErrorValues[ErrorType.OutDirMissing];
                        Directory.CreateDirectory(outputDir);

                        try
                        {
                            using (var outputFile = File.OpenWrite(outputFileName))
                            {
                                cryptoStream.CopyTo(outputFile);
                            }
                        }
                        catch (CryptographicException)
                        {
                            File.Delete(outputFileName);
                            return ErrorValues[ErrorType.FailedChecksum];
                        }

                        return new Some<Tuple<string, long>>(Tuple.Create(outputFileName, new FileInfo(outputFileName).Length));
                    }
                }
            }
        }
Пример #14
0
        public static JWE Parse(string token, string privateKey)
        {
            byte[] claimSet = null;
            EncryptedPayload payload = null;

            try
            {
                payload = EncryptedPayload.Parse(token);

                byte[] masterKey = null;
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                {
                    rsa.FromXmlString(privateKey);
                    masterKey = rsa.Decrypt(payload.EncryptedMasterKey, true);
                }

                byte[] additionalAuthenticatedData = payload.ToAdditionalAuthenticatedData();
                using (AuthenticatedAesCng aes = new AuthenticatedAesCng())
                {
                    aes.CngMode = CngChainingMode.Gcm;
                    aes.Key = masterKey;
                    aes.IV = payload.InitializationVector;
                    aes.AuthenticatedData = additionalAuthenticatedData;
                    aes.Tag = payload.Tag;

                    using (MemoryStream ms = new MemoryStream())
                    {
                        using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(),CryptoStreamMode.Write))
                        {
                            byte[] cipherText = payload.CipherText;
                            cs.Write(cipherText, 0, cipherText.Length);
                            cs.FlushFinalBlock();

                            claimSet = ms.ToArray();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new SecurityException("Invalid Token", ex);
            }

            var jwt = JsonConvert.DeserializeObject<JWE>(payload.Header);
            jwt.AsymmetricKey = privateKey;
            jwt.claims = JsonConvert.DeserializeObject<Dictionary<string, string>>(Encoding.UTF8.GetString(claimSet));

            TimeSpan ts = DateTime.UtcNow - epochStart;

            if (jwt.ExpiresOn < Convert.ToUInt64(ts.TotalSeconds))
                throw new SecurityException("Token has expired");

            return jwt;
        }
Пример #15
0
        public static Some <Tuple <string, long> > DecryptFile(string dstDir, string filename, byte[] key)
        {
            if (!File.Exists(filename))
            {
                return(ErrorValues[ErrorType.FileNoExist]);
            }

            using (var inputFile = File.OpenRead(filename))
            {
                var outerBuffer = new byte[TagStartPos];
                if (inputFile.Read(outerBuffer, 0, outerBuffer.Length) != outerBuffer.Length)
                {
                    return(ErrorValues[ErrorType.NotAnEncryptedFile]);
                }

                if (!outerBuffer.Take(OuterMagicHeader.Count).SequenceEqual(OuterMagicHeader))
                {
                    return(ErrorValues[ErrorType.MagicBytesMismatch]);
                }

                var tagLength = BitConverter.ToInt32(outerBuffer, OuterMagicHeader.Count);
                var ivLength  = BitConverter.ToInt32(outerBuffer, OuterMagicHeader.Count + sizeof(Int32));

                using (var aes = new AuthenticatedAesCng())
                {
                    outerBuffer = new byte[tagLength + ivLength];
                    if (inputFile.Read(outerBuffer, 0, outerBuffer.Length) != outerBuffer.Length)
                    {
                        return(ErrorValues[ErrorType.NotAnEncryptedFile]);
                    }

                    aes.CngMode = CngChainingMode.Gcm;
                    aes.Key     = key;
                    aes.Tag     = outerBuffer.Take(tagLength).ToArray();
                    aes.IV      = outerBuffer.Skip(tagLength).Take(ivLength).ToArray();

                    using (var dec = aes.CreateDecryptor())
                        using (var cryptoStream = new CryptoStream(inputFile, dec, CryptoStreamMode.Read))
                        {
                            var buf = new byte[MagicHeader.Count + sizeof(Int32)];
                            if (cryptoStream.Read(buf, 0, buf.Length) != buf.Length)
                            {
                                return(ErrorValues[ErrorType.CorruptFile]);
                            }

                            if (!buf.Take(MagicHeader.Count).SequenceEqual(MagicHeader))
                            {
                                return(ErrorValues[ErrorType.MagicBytesMismatch]);
                            }

                            var nameLength = BitConverter.ToInt32(buf, MagicHeader.Count);
                            buf = new byte[nameLength];
                            if (cryptoStream.Read(buf, 0, buf.Length) != buf.Length)
                            {
                                return(ErrorValues[ErrorType.CorruptFile]);
                            }
                            var fileName = Encoding.UTF8.GetString(buf, 0, buf.Length);

                            var outputFileName = Path.Combine(dstDir, fileName);
                            var outputDir      = Path.GetDirectoryName(outputFileName);

                            if (string.IsNullOrWhiteSpace(outputDir))
                            {
                                return(ErrorValues[ErrorType.OutDirMissing]);
                            }
                            Directory.CreateDirectory(outputDir);

                            try
                            {
                                using (var outputFile = File.OpenWrite(outputFileName))
                                {
                                    cryptoStream.CopyTo(outputFile);
                                }
                            }
                            catch (CryptographicException)
                            {
                                File.Delete(outputFileName);
                                return(ErrorValues[ErrorType.FailedChecksum]);
                            }

                            return(new Some <Tuple <string, long> >(Tuple.Create(outputFileName, new FileInfo(outputFileName).Length)));
                        }
                }
            }
        }