Пример #1
0
        /// <summary>
        /// Process the encrypted file's embedded access policy, remove embedded information, add AESTagData to encrypted file,
        /// Create a filter driver aware encrypted file. Then you can read the encrypted file transparently via filter driver encryption engine.
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="passPhrase"></param>
        /// <param name="lastError"></param>
        /// <returns></returns>
        public static bool ProcessSecureShareFile(string fileName, out string lastError)
        {
            bool ret = false;

            lastError = string.Empty;

            try
            {
                if (!File.Exists(fileName))
                {
                    lastError = fileName + " doesn't exist.";
                    return(false);
                }

                if (!fileName.EndsWith(SECURE_SHARE_FILE_EXTENSION))
                {
                    lastError = fileName + " extension is not correct.";
                    return(false);
                }

                FileAttributes attributes = File.GetAttributes(fileName);
                attributes = (~FileAttributes.ReadOnly) & attributes;
                File.SetAttributes(fileName, attributes);

                FileStream fs       = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
                long       fileSize = fs.Length;

                //read the last 4 bytes data, it is the total size of the embedded data.

                fs.Position = fileSize - 4;
                BinaryReader br            = new BinaryReader(fs);
                uint         sizeOfAESData = br.ReadUInt32();

                if (sizeOfAESData >= fileSize)
                {
                    lastError = fileName + " is not valid share encrypted file, the sizeOfAESData:" + sizeOfAESData + " >= file size:" + fileSize;
                    return(false);
                }

                fs.Position = fileSize - sizeOfAESData;

                //Read the embedded data
                byte[] AESBuffer = new byte[sizeOfAESData];
                fs.Read(AESBuffer, 0, (int)sizeOfAESData);

                //decrypt the embedded data, since the last 4 bytes is not encrypted, after decryption,need to write the clear size back.
                FilterAPI.AESEncryptDecryptBuffer(AESBuffer, 0, null, null);

                //since the last 4 bytes for sizeOfAESData is not encrypted, we need to put back the clear value back.
                MemoryStream ms = new MemoryStream(AESBuffer);
                ms.Position = 0;
                br          = new BinaryReader(ms);
                uint verificationKey = br.ReadUInt32();

                //verify if this is the valid embedded data.
                if (verificationKey != AES_VERIFICATION_KEY)
                {
                    lastError = fileName + " is not valid share encrypted file, the encryption key:" + verificationKey + " is not valid.";
                    return(false);
                }

                //write back the size of embedded data here.
                ms.Position = ms.Length - 4;
                BinaryWriter bw = new BinaryWriter(ms);
                bw.Write(sizeOfAESData);

                //Remove the embedded data, this is the original file size without the embedded information.
                fs.SetLength(fileSize - sizeOfAESData);

                fs.Close();
                fs = null;

                string newFileName = fileName.Remove(fileName.Length - SECURE_SHARE_FILE_EXTENSION.Length);

                File.Move(fileName, newFileName);
                //add the DR data to the encrypted file as a tag data.
                ret = FilterAPI.EmbedDRPolicyDataToFile(newFileName, AESBuffer, out lastError);
            }
            catch (Exception ex)
            {
                ret       = false;
                lastError = "ProcessSecureShareFile " + fileName + " failed with error:" + ex.Message;
            }


            return(ret);
        }
Пример #2
0
        /// <summary>
        /// Create an encrypted file with embedded access control policy, distribute the encrypted file via internet,
        /// only the authorized users and processes can access the encrypted file.
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="passPhrase"></param>
        /// <param name="policy"></param>
        /// <param name="lastError"></param>
        /// <returns></returns>
        public static bool EncryptFileWithEmbeddedPolicy(string fileName, string passPhrase, AESAccessPolicy policy, out string lastError)
        {
            bool       ret = false;
            FileStream fs  = null;

            lastError = string.Empty;

            try
            {
                if (!File.Exists(fileName))
                {
                    lastError = fileName + " doesn't exist.";
                    return(false);
                }

                FileAttributes attributes = File.GetAttributes(fileName);
                attributes = (~FileAttributes.ReadOnly) & attributes;
                File.SetAttributes(fileName, attributes);

                byte[] encryptionKey = Utils.GetKeyByPassPhrase(passPhrase);
                byte[] iv            = Utils.GetRandomIV();

                //encrypt the file with encryption key and a random iv key.
                ret = FilterAPI.AESEncryptFile(fileName, (uint)encryptionKey.Length, encryptionKey, (uint)iv.Length, iv, false);
                if (!ret)
                {
                    lastError = "Encrypt file " + fileName + " failed with error:" + FilterAPI.GetLastErrorMessage();
                    return(ret);
                }

                fs = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.Read);
                long fileSize = fs.Length;

                MemoryStream ms = new MemoryStream();
                BinaryWriter bw = new BinaryWriter(ms);
                bw.Write(AES_VERIFICATION_KEY);
                bw.Write(policy.AESFlags);
                bw.Write(iv.Length);
                bw.Write(iv);
                bw.Write(policy.ExpireTime);

                bw.Write(policy.AccessFlags);
                bw.Write(fileSize);
                bw.Write(policy.LengthOfIncludeProcessNames);
                policy.OffsetOfIncludeProcessNames = (uint)ms.Length + 7 * 4;
                bw.Write(policy.OffsetOfIncludeProcessNames);
                bw.Write(policy.LengthOfExcludeProcessNames);
                policy.OffsetOfExcludeProcessNames = policy.OffsetOfIncludeProcessNames + policy.LengthOfIncludeProcessNames;
                bw.Write(policy.OffsetOfExcludeProcessNames);
                bw.Write(policy.LengthOfIncludeUserNames);
                policy.OffsetOfIncludeUserNames = policy.OffsetOfExcludeProcessNames + policy.LengthOfExcludeProcessNames;
                bw.Write(policy.OffsetOfIncludeUserNames);
                bw.Write(policy.LengthOfExcludeUserNames);
                policy.OffsetOfExcludeUserNames = policy.OffsetOfIncludeUserNames + policy.LengthOfIncludeUserNames;
                bw.Write(policy.OffsetOfExcludeUserNames);

                byte[] strBuffer;
                if (policy.LengthOfIncludeProcessNames > 0)
                {
                    strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.IncludeProcessNames);
                    bw.Write(strBuffer);
                }

                if (policy.LengthOfExcludeProcessNames > 0)
                {
                    strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ExcludeProcessNames);
                    bw.Write(strBuffer);
                }

                if (policy.LengthOfIncludeUserNames > 0)
                {
                    strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.IncludeUserNames);
                    bw.Write(strBuffer);
                }

                if (policy.LengthOfExcludeUserNames > 0)
                {
                    strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ExcludeUserNames);
                    bw.Write(strBuffer);
                }

                uint sizeOfAESData = (uint)ms.Length + 4;

                byte[] AESBuffer = ms.ToArray();

                //encrypt the access policy except the sizeOfAESData;
                FilterAPI.AESEncryptDecryptBuffer(AESBuffer, 0, encryptionKey, FilterAPI.DEFAULT_IV_TAG);

                //append the access policy to the encrypted file.
                fs.Write(AESBuffer, 0, AESBuffer.Length);
                fs.Write(BitConverter.GetBytes(sizeOfAESData), 0, 4);

                //set the encrypted file to readonly here.
                attributes = File.GetAttributes(fileName) | FileAttributes.ReadOnly;
                File.SetAttributes(fileName, attributes);
            }
            catch (Exception ex)
            {
                ret       = false;
                lastError = "EncryptFileAndEmbedExpireTime " + fileName + " failed with error:" + ex.Message;
            }
            finally
            {
                if (null != fs)
                {
                    fs.Close();
                }
            }

            return(ret);
        }
Пример #3
0
        private static byte[] GetPolicyBuffer(long fileSize, DRPolicyData policy, byte[] iv, byte[] encryptionKey)
        {
            MemoryStream ms = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms);

            bw.Write(AES_VERIFICATION_KEY);
            bw.Write((uint)(policy.AESFlags));
            bw.Write(iv.Length);
            bw.Write(iv);
            bw.Write(encryptionKey.Length);

            if (encryptionKey.Length < 32)
            {
                //the struture always keep 32 bytes for encryption key.
                Array.Resize(ref encryptionKey, 32);
            }

            bw.Write(encryptionKey);
            bw.Write(policy.CreationTime);
            bw.Write(policy.ExpireTime);
            bw.Write((uint)policy.AccessFlags);
            bw.Write(fileSize);
            bw.Write(policy.LengthOfIncludeProcessNames);

            //the first offset lenght = current position + 13*4
            //    sizeof(OffsetOfIncludeProcessNames)  +  sizeof(OffsetOfExcludeProcessNames) + sizeof(LengthOfExcludeProcessNames)
            // +  sizeof(OffsetOfIncludeUserNames) + sizeof(LengthOfIncludeUserNames) +  sizeof(OffsetOfExcludeUserNames) + sizeof(LengthOfExcludeUserNames)
            // +  sizeof(OffsetOfAccountName) + sizeof(LengthOfAccountName) +  sizeof(OffsetOfComputerIds) + sizeof(LengthOfComputerIds)
            // +  sizeof(LengthOfUserPassword) + sizeof(OffsetOfUserPassword)

            policy.OffsetOfIncludeProcessNames = (uint)ms.Length + 13 * 4;
            bw.Write(policy.OffsetOfIncludeProcessNames);

            bw.Write(policy.LengthOfExcludeProcessNames);
            policy.OffsetOfExcludeProcessNames = policy.OffsetOfIncludeProcessNames + policy.LengthOfIncludeProcessNames;
            bw.Write(policy.OffsetOfExcludeProcessNames);

            bw.Write(policy.LengthOfIncludeUserNames);
            policy.OffsetOfIncludeUserNames = policy.OffsetOfExcludeProcessNames + policy.LengthOfExcludeProcessNames;
            bw.Write(policy.OffsetOfIncludeUserNames);

            bw.Write(policy.LengthOfExcludeUserNames);
            policy.OffsetOfExcludeUserNames = policy.OffsetOfIncludeUserNames + policy.LengthOfIncludeUserNames;
            bw.Write(policy.OffsetOfExcludeUserNames);

            bw.Write(policy.LengthOfAccountName);
            policy.OffsetOfAccountName = policy.OffsetOfExcludeUserNames + policy.LengthOfExcludeUserNames;
            bw.Write(policy.OffsetOfAccountName);

            bw.Write(policy.LengthOfComputerIds);
            policy.OffsetOfComputerIds = policy.OffsetOfAccountName + policy.LengthOfAccountName;
            bw.Write(policy.OffsetOfComputerIds);

            bw.Write(policy.LengthOfUserPassword);
            policy.OffsetOfUserPassword = policy.OffsetOfComputerIds + policy.LengthOfComputerIds;
            bw.Write(policy.OffsetOfUserPassword);


            byte[] strBuffer;
            if (policy.LengthOfIncludeProcessNames > 0)
            {
                strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.IncludeProcessNames);
                bw.Write(strBuffer);
            }

            if (policy.LengthOfExcludeProcessNames > 0)
            {
                strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ExcludeProcessNames);
                bw.Write(strBuffer);
            }

            if (policy.LengthOfIncludeUserNames > 0)
            {
                strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.IncludeUserNames);
                bw.Write(strBuffer);
            }

            if (policy.LengthOfExcludeUserNames > 0)
            {
                strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ExcludeUserNames);
                bw.Write(strBuffer);
            }

            if (policy.LengthOfAccountName > 0)
            {
                strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.AccountName);
                bw.Write(strBuffer);
            }

            if (policy.LengthOfComputerIds > 0)
            {
                strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ComputerIds);
                bw.Write(strBuffer);
            }

            if (policy.LengthOfUserPassword > 0)
            {
                strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.UserPassword);
                bw.Write(strBuffer);
            }

            byte[] AESBuffer = ms.ToArray();

            //encrypt the access policy except the sizeOfAESData;
            FilterAPI.AESEncryptDecryptBuffer(AESBuffer, 0, null, null);

            return(AESBuffer);
        }
Пример #4
0
        /// <summary>
        /// Process the encrypted file's embedded access policy, remove embedded information, add AESTagData to encrypted file,
        /// Create a filter driver aware encrypted file. Then you can read the encrypted file transparently via filter driver encryption engine.
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="passPhrase"></param>
        /// <param name="lastError"></param>
        /// <returns></returns>
        public static bool ConvertFileToFilterDriverAwareEncryptFile(string fileName, string passPhrase, out string lastError)
        {
            bool ret = false;

            lastError = string.Empty;

            try
            {
                if (!File.Exists(fileName))
                {
                    lastError = fileName + " doesn't exist.";
                    return(false);
                }

                FileAttributes attributes = File.GetAttributes(fileName);
                attributes = (~FileAttributes.ReadOnly) & attributes;
                File.SetAttributes(fileName, attributes);

                FileStream fs       = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
                long       fileSize = fs.Length;

                //read the last 4 bytes data, it is the total size of the embedded data.

                fs.Position = fileSize - 4;
                BinaryReader br            = new BinaryReader(fs);
                uint         sizeOfAESData = br.ReadUInt32();

                if (sizeOfAESData >= fileSize)
                {
                    lastError = fileName + " is not valid share encrypted file, the sizeOfAESData:" + sizeOfAESData + " >= file size:" + fileSize;
                    return(false);
                }

                fs.Position = fileSize - sizeOfAESData;

                //Read the embedded data
                byte[] AESBuffer = new byte[sizeOfAESData];
                fs.Read(AESBuffer, 0, (int)sizeOfAESData);

                //decrypt the embedded data, since the last 4 bytes is not encrypted, after decryption,need to write the clear size back.
                byte[] encryptionKey = Utils.GetKeyByPassPhrase(passPhrase);
                FilterAPI.AESEncryptDecryptBuffer(AESBuffer, 0, encryptionKey, FilterAPI.DEFAULT_IV_TAG);

                //since the last 4 bytes for sizeOfAESData is not encrypted, we need to put back the clear value back.
                MemoryStream ms = new MemoryStream(AESBuffer);
                ms.Position = 0;
                br          = new BinaryReader(ms);
                uint verificationKey = br.ReadUInt32();

                //verify if this is the valid embedded data.
                if (verificationKey != AES_VERIFICATION_KEY)
                {
                    lastError = fileName + " is not valid share encrypted file, the encryption key:" + verificationKey + " is not valid.";
                    return(false);
                }

                //write back the size of embedded data here.
                ms.Position = ms.Length - 4;
                BinaryWriter bw = new BinaryWriter(ms);
                bw.Write(sizeOfAESData);

                //Remove the embedded data, this is the original file size without the embedded information.
                fs.SetLength(fileSize - sizeOfAESData);

                fs.Close();
                fs = null;

                //add the embedded data to the tag data of the encrypted file.
                ret = FilterAPI.AddAESData(fileName, AESBuffer, out lastError);
            }
            catch (Exception ex)
            {
                ret       = false;
                lastError = "EncryptFileAndEmbedExpireTime " + fileName + " failed with error:" + ex.Message;
            }


            return(ret);
        }