Exemplo n.º 1
0
        private void FinishEncryption()
        {
            TEncryptionParameters EncParams = GetEncryptionParams(Protection);
            AesManaged            EncEngine = TEncryptionUtils.CreateEngine(EncParams);

            TAgileEncryptionKey DataKey = TAgileEncryptionKey.CreateForWriting(null, EncEngine.KeySize / 8);

            DataKey.Key = TEncryptionUtils.GetRandom(DataKey.KeySizeInBytes);

            TAgileEncryptionKey KeyKey = TAgileEncryptionKey.CreateForWriting(Protection.OpenPassword, EncEngine.KeySize / 8);

            byte[] WorkLen = new byte[8];
            BitOps.SetCardinal(WorkLen, 0, WorkingStream.Length - WorkStreamZeroPos);

            EncryptStream(EncEngine, DataKey, WorkLen);

            using (MemoryStream ms = new MemoryStream())
            {
                using (TOle2File Ole2File = new TOle2File(GetEmptyEncryptedFile()))
                {
                    Ole2File.PrepareForWrite(ms, XlsxConsts.EncryptionInfoString, new string[0]);
                    CreateInfoStream(Ole2File, EncEngine, EncParams, KeyKey, DataKey);
                }

                ms.Position = 0;

                using (TOle2File Ole2File = new TOle2File(ms))
                {
                    Ole2File.PrepareForWrite(TargetStream, XlsxConsts.ContentString, new string[0]);
                    WorkingStream.Position = 0;
                    TEncryptionUtils.CopyStream(WorkingStream, Ole2File);
                }
            }
        }
Exemplo n.º 2
0
        private static void WriteAgileCipherParams(XmlWriter xml, TEncryptionParameters EncParams, TAgileEncryptionKey Key)
        {
            xml.WriteAttributeString("saltSize", Convert.ToString(Key.Salt.Length, CultureInfo.InvariantCulture));
            xml.WriteAttributeString("blockSize", Convert.ToString(Key.BlockSize, CultureInfo.InvariantCulture));
            xml.WriteAttributeString("keyBits", Convert.ToString(Key.KeySizeInBytes * 8, CultureInfo.InvariantCulture));
            xml.WriteAttributeString("hashSize", Convert.ToString(Key.HashSizeBytes(), CultureInfo.InvariantCulture)); //sha1 hash size

            xml.WriteAttributeString("cipherAlgorithm", "AES");
            switch (EncParams.ChainingMode)
            {
            case CipherMode.CBC:
                xml.WriteAttributeString("cipherChaining", "ChainingModeCBC");
                break;

            case CipherMode.CFB:
                xml.WriteAttributeString("cipherChaining", "ChainingModeCFB");
                break;

            case CipherMode.CTS:
            case CipherMode.ECB:
            case CipherMode.OFB:
            default:
                XlsMessages.ThrowException(XlsErr.ErrNotSupportedEncryption); break;
            }

            xml.WriteAttributeString("hashAlgorithm", "SHA1");
            xml.WriteAttributeString("saltValue", Convert.ToBase64String(Key.Salt));
        }
Exemplo n.º 3
0
        private static Stream DecryptStream(TOle2File DataStream, TEncryptionParameters EncParams, TEncryptionKey Key)
        {
            DataStream.SelectStream(XlsxConsts.ContentString);
            byte[] EncryptedSize = new byte[8];
            DataStream.Read(EncryptedSize, EncryptedSize.Length);
            AesManaged       Engine    = null;
            ICryptoTransform Decryptor = null;

            try
            {
                Engine = TEncryptionUtils.CreateEngine(EncParams);
                if (!Key.VariableIV)
                {
                    Decryptor = Engine.CreateDecryptor(Key.Key, Key.IV);
                }
                return(new TXlsxCryptoStreamReader(DataStream, BitOps.GetCardinal(EncryptedSize, 0), Engine, Decryptor, Key));
            }
            catch
            {
                if (Engine != null)
                {
                    ((IDisposable)Engine).Dispose();
                }
                if (Decryptor != null)
                {
                    Decryptor.Dispose();
                }
                throw;
            }
        }
Exemplo n.º 4
0
        internal override bool VerifyPass(string Password, TEncryptionParameters EncParams, TEncryptionKey Key)
        {
            if (!base.VerifyPass(Password, EncParams, Key))
            {
                return(false);
            }

            Key.CalcKey(TStandardEncryptionKey.BlockKey, null);
            byte[] DecriptedVerifier;
            byte[] DecriptedVerifierHash;
            using (AesManaged Engine = TEncryptionUtils.CreateEngine(EncParams))
            {
                using (ICryptoTransform Decryptor = Engine.CreateDecryptor(Key.Key, Key.IV))
                {
                    DecriptedVerifier     = DecryptBytes(EncryptedVerifier, Decryptor, -1);
                    DecriptedVerifierHash = DecryptBytes(EncryptedVerifierHash, Decryptor, -1);
                }
            }

            using (HashAlgorithm hasher = TEncryptionKey.CreateHasher())
            {
                byte[] DecriptedVerifierHash2 = hasher.ComputeHash(DecriptedVerifier);
                if (!FlxUtils.CompareMem(DecriptedVerifierHash, 0, DecriptedVerifierHash2, 0, VerifierHashSizeBytes))
                {
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 5
0
        private static void ReadAgileCipherParams(XmlReader xml, TEncryptionParameters EncParams, TEncryptionKey Key)
        {
            int SaltSize  = Convert.ToInt32(xml.GetAttribute("saltSize"), CultureInfo.InvariantCulture);
            int BlockSize = Convert.ToInt32(xml.GetAttribute("blockSize"), CultureInfo.InvariantCulture);

            Key.BlockSize = BlockSize;
            if (BlockSize != 0x10)
            {
                XlsMessages.ThrowException(XlsErr.ErrNotSupportedEncryption);
            }

            int KeyBits = Convert.ToInt32(xml.GetAttribute("keyBits"), CultureInfo.InvariantCulture);

            Key.KeySizeInBytes = KeyBits / 8;

            switch (KeyBits)
            {
            case 128: EncParams.Algorithm = TEncryptionAlgorithm.AES_128; break;

            case 192: EncParams.Algorithm = TEncryptionAlgorithm.AES_192; break;

            case 256: EncParams.Algorithm = TEncryptionAlgorithm.AES_256; break;

            default:
                XlsMessages.ThrowException(XlsErr.ErrNotSupportedEncryption);
                break;
            }
            string CipherAlgo = xml.GetAttribute("cipherAlgorithm");

            if (!string.Equals(CipherAlgo, "AES", StringComparison.InvariantCulture))
            {
                XlsMessages.ThrowException(XlsErr.ErrNotSupportedEncryption);
            }

            string CipherChaining = xml.GetAttribute("cipherChaining");

            switch (CipherChaining)
            {
            case "ChainingModeCBC": EncParams.ChainingMode = CipherMode.CBC; break;

            case "ChainingModeCFB": EncParams.ChainingMode = CipherMode.CFB; break;

            default:
                XlsMessages.ThrowException(XlsErr.ErrNotSupportedEncryption); break;
            }

            string HashAlgorithm = xml.GetAttribute("hashAlgorithm");

            if (HashAlgorithm != "SHA1" && HashAlgorithm != "SHA-1")
            {
                XlsMessages.ThrowException(XlsErr.ErrNotSupportedEncryption);
            }

            Key.Salt = Convert.FromBase64String(xml.GetAttribute("saltValue"));
            if (Key.Salt == null || SaltSize != Key.Salt.Length)
            {
                XlsMessages.ThrowException(XlsErr.ErrNotSupportedEncryption);
            }
        }
Exemplo n.º 6
0
        public static TEncryptionParameters CreateStandard(TEncryptionAlgorithm aAlgorithm)
        {
            TEncryptionParameters Result = new TEncryptionParameters();

            Result.Algorithm    = aAlgorithm;
            Result.ChainingMode = CipherMode.ECB;

            return(Result);
        }
Exemplo n.º 7
0
        private static TEncryptionParameters GetEncryptionParams(TProtection Protection)
        {
            TEncryptionParameters Result = new TEncryptionParameters();

            Result.Algorithm    = Protection.EncryptionAlgorithmXlsx;
            Result.ChainingMode = CipherMode.CBC;
            Result.Padding      = PaddingMode.Zeros;
            return(Result);
        }
Exemplo n.º 8
0
        public static AesManaged CreateEngine(TEncryptionParameters EncryptionParameters)
        {
            AesManaged Engine = new AesManaged(); //using

            Engine.KeySize = CalcKeySizeInBits(EncryptionParameters);

            Engine.Padding = EncryptionParameters.Padding;
            Engine.Mode    = EncryptionParameters.ChainingMode;
            return(Engine);
        }
Exemplo n.º 9
0
        private void CreateInfoStream(TOle2File DataStream, AesManaged EncEngine, TEncryptionParameters EncParams, TAgileEncryptionKey KeyKey, TAgileEncryptionKey DataKey)
        {
            DataStream.Write16(0x0004);
            DataStream.Write16(0x0004);
            DataStream.Write32(0x00040);

            byte[] InfoStreamXml = GetInfoStreamXml(EncEngine, EncParams, KeyKey, DataKey);
            DataStream.Write(InfoStreamXml, InfoStreamXml.Length);
            byte[] pad = new byte[4098 - InfoStreamXml.Length]; //Our Ole2 implementation will fill a sector with 0 so it doesn't go to the ministream. Those 0 will confuse Excel, so we will write spaces.
            for (int i = 0; i < pad.Length; i++)
            {
                pad[i] = 32;
            }
            DataStream.Write(pad, pad.Length);
        }
Exemplo n.º 10
0
        internal virtual bool VerifyPass(string Password, TEncryptionParameters EncParams, TEncryptionKey Key)
        {
            if (Password == null)
            {
                XlsMessages.ThrowException(XlsErr.ErrInvalidPassword);
            }
            if (Password.Length > 255)
            {
                XlsMessages.ThrowException(XlsErr.ErrPasswordTooLong);
            }

            Key.Password = Encoding.Unicode.GetBytes(Password);
            Key.PreCalcKey();

            return(true);
        }
Exemplo n.º 11
0
        private static int CalcKeySizeInBits(TEncryptionParameters EncryptionParameters)
        {
            switch (EncryptionParameters.Algorithm)
            {
            case TEncryptionAlgorithm.AES_128:
                return(0x80);

            case TEncryptionAlgorithm.AES_192:
                return(0xC0);

            case TEncryptionAlgorithm.AES_256:
                return(0x100);
            }
            XlsMessages.ThrowException(XlsErr.ErrNotSupportedEncryption);
            return(0);
        }
Exemplo n.º 12
0
        private static Stream ReadAgileEncryptionInfo(TOle2File DataStream, TEncryptionData Encryption)
        {
            byte[] Enc = new byte[DataStream.Length - DataStream.Position];
            DataStream.Read(Enc, Enc.Length);

            TEncryptionParameters DataEncParams = new TEncryptionParameters();
            TAgileEncryptionKey   DataKey       = new TAgileEncryptionKey();

            TAgileEncryptionVerifier KeyVerifier  = new TAgileEncryptionVerifier();
            TEncryptionParameters    KeyEncParams = new TEncryptionParameters();
            TAgileEncryptionKey      KeyKey       = new TAgileEncryptionKey();

            using (MemoryStream ms = new MemoryStream(Enc))
            {
                using (XmlReader xml = XmlReader.Create(ms))
                {
                    xml.ReadStartElement("encryption"); //goes to keyData

                    ReadAgileCipherParams(xml, DataEncParams, DataKey);

                    xml.ReadStartElement("keyData"); //goes to dataIntegrity

                    //We are not checking data integrity at the moment.
                    //DataIntegrity.EncryptedHMacKey = Convert.FromBase64String(xml.GetAttribute("encryptedHmacKey"));
                    //DataIntegrity.EncryptedHmacValue = Convert.FromBase64String(xml.GetAttribute("encryptedHmacValue"));

                    xml.ReadStartElement("dataIntegrity"); //goes to keyEncryptors
                    xml.ReadStartElement("keyEncryptors"); //goes to keyEncryptor
                    xml.ReadStartElement("keyEncryptor");  //goes to encryptedKey
                    KeyKey.SpinCount = Convert.ToInt32(xml.GetAttribute("spinCount"), CultureInfo.InvariantCulture);
                    ReadAgileCipherParams(xml, KeyEncParams, KeyKey);
                    KeyVerifier.EncryptedVerifierHashInput = Convert.FromBase64String(xml.GetAttribute("encryptedVerifierHashInput"));
                    KeyVerifier.EncryptedVerifierHashValue = Convert.FromBase64String(xml.GetAttribute("encryptedVerifierHashValue"));
                    KeyVerifier.EncryptedKeyValue          = Convert.FromBase64String(xml.GetAttribute("encryptedKeyValue"));
                }
            }

            CheckPassword(Encryption, KeyVerifier, KeyEncParams, KeyKey);
            DataKey.Key      = KeyKey.Key;
            DataKey.Password = KeyKey.Password;
            DataKey.CalcDataIV(0);
            return(DecryptStream(DataStream, DataEncParams, DataKey));
        }
Exemplo n.º 13
0
        internal override bool VerifyPass(string Password, TEncryptionParameters EncParams, TEncryptionKey Key)
        {
            if (!base.VerifyPass(Password, EncParams, Key))
            {
                return(false);
            }

            using (AesManaged Engine = TEncryptionUtils.CreateEngine(EncParams))
            {
                byte[] DecriptedVerifierHashInput;
                Key.CalcKey(TAgileEncryptionKey.VerifierHashInputBlockKey, null);
                using (ICryptoTransform Decryptor = Engine.CreateDecryptor(Key.Key, Key.IV))
                {
                    DecriptedVerifierHashInput = DecryptBytes(EncryptedVerifierHashInput, Decryptor, Key.Salt.Length); //this is the value padded to a blocksize multiple. We want only the Salt.Length initial bytes.
                    DecriptedVerifierHashInput = Key.Hash(DecriptedVerifierHashInput);
                }

                byte[] DecriptedVerifierHashValue;
                Key.CalcKey(TAgileEncryptionKey.VerifierHashValueBlockKey, null);
                using (ICryptoTransform Decryptor = Engine.CreateDecryptor(Key.Key, Key.IV))
                {
                    DecriptedVerifierHashValue = DecryptBytes(EncryptedVerifierHashValue, Decryptor, DecriptedVerifierHashInput.Length); //this is the 20 byte value of the hash + 12 "0" so it goes up to 32. (32 is 2*blocksize)
                }

                if (!FlxUtils.CompareMem(DecriptedVerifierHashValue, DecriptedVerifierHashInput))
                {
                    return(false);
                }

                byte[] DecriptedKeyValue;
                Key.CalcKey(TAgileEncryptionKey.VerifierKeyValueBlockKey, null);
                using (ICryptoTransform Decryptor = Engine.CreateDecryptor(Key.Key, Key.IV))
                {
                    DecriptedKeyValue = DecryptBytes(EncryptedKeyValue, Decryptor, Key.KeySizeInBytes);
                }

                Key.Key = DecriptedKeyValue;
            }

            return(true);
        }
Exemplo n.º 14
0
        private static Stream ReadStandardEncryptionInfo(TOle2File DataStream, TEncryptionData Encryption)
        {
            byte[] RecordHeaderLen = new byte[4];
            DataStream.Read(RecordHeaderLen, RecordHeaderLen.Length);

            long EncryptionHeaderSize = BitOps.GetCardinal(RecordHeaderLen, 0);

            byte[] EncryptionHeader = new byte[EncryptionHeaderSize];
            DataStream.Read(EncryptionHeader, EncryptionHeader.Length);
            long AlgId   = BitOps.GetCardinal(EncryptionHeader, 8);
            long KeyBits = BitOps.GetCardinal(EncryptionHeader, 16);

            TEncryptionParameters EncParams = TEncryptionParameters.CreateStandard(GetStandardEncAlg(AlgId));

            byte[] VerifierBytes = new byte[DataStream.Length - DataStream.Position];
            DataStream.Read(VerifierBytes, VerifierBytes.Length);
            TStandardEncryptionVerifier Verifier = ReadStandardVerifier(VerifierBytes);
            TEncryptionKey Key = new TStandardEncryptionKey(ReadStandardSalt(VerifierBytes), (int)KeyBits / 8);

            CheckPassword(Encryption, Verifier, EncParams, Key);

            return(DecryptStream(DataStream, EncParams, Key));
        }
Exemplo n.º 15
0
        private static void CheckPassword(TEncryptionData Encryption, TEncryptionVerifier Verifier, TEncryptionParameters EncParams, TEncryptionKey Key)
        {
            if (Verifier.VerifyPass(XlsConsts.EmptyExcelPassword, EncParams, Key))
            {
                return; //workbook password protected
            }

            string Password = Encryption.ReadPassword;

            if (Encryption.OnPassword != null)
            {
                OnPasswordEventArgs ea = new OnPasswordEventArgs(Encryption.Xls);
                Encryption.OnPassword(ea);
                Encryption.ReadPassword = ea.Password;
                Password = ea.Password;
            }

            if (!Verifier.VerifyPass(Password, EncParams, Key))
            {
                XlsMessages.ThrowException(XlsErr.ErrInvalidPassword);
            }
        }
Exemplo n.º 16
0
        private byte[] GetInfoStreamXml(AesManaged EncEngine, TEncryptionParameters EncParams, TAgileEncryptionKey KeyKey, TAgileEncryptionKey DataKey)
        {
            const string KeyEncryptorPasswordNamespace = "http://schemas.microsoft.com/office/2006/keyEncryptor/password";

            using (MemoryStream ms = new MemoryStream())
            {
                XmlWriterSettings Settings = new XmlWriterSettings();
                Settings.Encoding = new System.Text.UTF8Encoding(false);
                using (XmlWriter xml = XmlWriter.Create(ms, Settings))
                {
                    xml.WriteStartDocument(true);
                    xml.WriteStartElement("encryption", "http://schemas.microsoft.com/office/2006/encryption");
                    xml.WriteAttributeString("xmlns", "p", null, KeyEncryptorPasswordNamespace);
                    xml.WriteStartElement("keyData");
                    WriteAgileCipherParams(xml, EncParams, DataKey);
                    xml.WriteEndElement();

                    xml.WriteStartElement("dataIntegrity");

                    byte[] HMacKeyBlockKey = new byte[] { 0x5f, 0xb2, 0xad, 0x01, 0x0c, 0xb9, 0xe1, 0xf6 };
                    DataKey.CalcDataIV(HMacKeyBlockKey);
                    byte[] HMacKey = TEncryptionUtils.GetRandom((int)DataKey.HashSizeBytes());
                    using (ICryptoTransform Encryptor = EncEngine.CreateEncryptor(DataKey.Key, DataKey.IV))
                    {
                        byte[] EncryptedHMacKey = TAgileEncryptionVerifier.EncryptBytes(HMacKey, Encryptor, DataKey.BlockSize);
                        xml.WriteAttributeString("encryptedHmacKey", Convert.ToBase64String(EncryptedHMacKey));
                    }

                    HMAC HMacCalc = new HMACSHA1(HMacKey);
                    WorkingStream.Position = 0;
                    byte[] HMac            = HMacCalc.ComputeHash(WorkingStream);
                    byte[] HMacValBlockKey = new byte[] { 0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, 0x33 };
                    DataKey.CalcDataIV(HMacValBlockKey);
                    using (ICryptoTransform Encryptor = EncEngine.CreateEncryptor(DataKey.Key, DataKey.IV))
                    {
                        byte[] EncryptedHMacValue = TAgileEncryptionVerifier.EncryptBytes(HMac, Encryptor, DataKey.BlockSize);
                        xml.WriteAttributeString("encryptedHmacValue", Convert.ToBase64String(EncryptedHMacValue));
                    }

                    xml.WriteEndElement();
                    xml.WriteStartElement("keyEncryptors");
                    xml.WriteStartElement("keyEncryptor");
                    xml.WriteAttributeString("uri", KeyEncryptorPasswordNamespace);
                    xml.WriteStartElement("encryptedKey", KeyEncryptorPasswordNamespace);


                    xml.WriteAttributeString("spinCount", Convert.ToString(KeyKey.SpinCount, CultureInfo.InvariantCulture));
                    WriteAgileCipherParams(xml, EncParams, KeyKey);

                    byte[] RandData = TEncryptionUtils.GetRandom(KeyKey.Salt.Length);
                    KeyKey.CalcKey(TAgileEncryptionKey.VerifierHashInputBlockKey, null);
                    using (ICryptoTransform Encryptor = EncEngine.CreateEncryptor(KeyKey.Key, KeyKey.IV))
                    {
                        byte[] EncryptedVerifierHashInput = TAgileEncryptionVerifier.EncryptBytes(RandData, Encryptor, KeyKey.BlockSize);
                        xml.WriteAttributeString("encryptedVerifierHashInput", Convert.ToBase64String(EncryptedVerifierHashInput));
                    }


                    KeyKey.CalcKey(TAgileEncryptionKey.VerifierHashValueBlockKey, null);
                    using (ICryptoTransform Encryptor = EncEngine.CreateEncryptor(KeyKey.Key, KeyKey.IV))
                    {
                        byte[] EncryptedVerifierHashValue = TAgileEncryptionVerifier.EncryptBytes(KeyKey.Hash(RandData), Encryptor, KeyKey.BlockSize);
                        xml.WriteAttributeString("encryptedVerifierHashValue", Convert.ToBase64String(EncryptedVerifierHashValue));
                    }

                    KeyKey.CalcKey(TAgileEncryptionKey.VerifierKeyValueBlockKey, null);
                    using (ICryptoTransform Encryptor = EncEngine.CreateEncryptor(KeyKey.Key, KeyKey.IV))
                    {
                        byte[] EncryptedKeyValue = TAgileEncryptionVerifier.EncryptBytes(DataKey.Key, Encryptor, KeyKey.BlockSize);
                        xml.WriteAttributeString("encryptedKeyValue", Convert.ToBase64String(EncryptedKeyValue));
                    }
                    xml.WriteEndElement();
                    xml.WriteEndElement();
                    xml.WriteEndElement();

                    xml.WriteEndElement();
                    xml.WriteEndDocument();
                }
                return(ms.ToArray());
            }
        }