示例#1
0
        /// <summary>
        /// Updates contents of encrypted file using another unencrypted file. Iv and signature of the file is also changed.
        /// </summary>
        /// <param name="updateFile">Unencrypted file used to update encrypted file.</param>
        /// <param name="oldEncryptedFile">Encrypted file in its raw form that is being updated.</param>
        /// <param name="userId">Id of the user updating the file. File can only be updated by a file owner.</param>
        /// <param name="userPrivateKey">Private RSA key of the user updating the file.</param>
        /// <returns>Updated encrypted file in its raw form.</returns>
        public byte[] Update(OriginalFile updateFile, byte[] oldEncryptedFile, int userId, RSAParameters userPrivateKey)
        {
            if (userId != GetFileOwnerId(oldEncryptedFile))
            {
                throw new Exception("Only a file owner can modify its content.");
            }

            var offset = 0;

            ((StandardInformation)Headers[0]).ParseStandardInformation(oldEncryptedFile, offset);
            // update altered and read time of the file
            ((StandardInformation)Headers[0]).AlteredTime = ((StandardInformation)Headers[0]).ReadTime = DateTime.Now;
            // update id of the user who is updating file; ATimeUserId doesn't need to change since only a file owner can edit the file
            ((StandardInformation)Headers[0]).RTimeUserId = (uint)userId;

            offset += (int)((StandardInformation)Headers[0]).GetSaveLength();

            ((SecurityDescriptor)Headers[1]).ParseSecurityDescriptor(oldEncryptedFile, ref offset);

            // update file signature
            SignFile(updateFile.FileContent, ref userPrivateKey);


            // update IV value
            new RNGCryptoServiceProvider().GetBytes(((SecurityDescriptor)Headers[1]).IV);

            Headers[2] = new Data(updateFile.FileContent,
                                  AlgorithmUtility.GetAlgorithmFromNameSignature(((SecurityDescriptor)Headers[1]).AlgorithmNameSignature,
                                                                                 ((SecurityDescriptor)Headers[1]).GetKey(userId, userPrivateKey), ((SecurityDescriptor)Headers[1]).IV));

            // update the file size
            ((StandardInformation)Headers[0]).TotalLength = (uint)((Data)Headers[2]).EncryptedData.Length;

            return(Flush());
        }
示例#2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SecurityDescriptor"/> class with the specified parameters.
        /// This constructor is used when a file is first encrypted.
        /// </summary>
        /// <param name="ownerId">Users Id from the database.</param>
        /// <param name="algorithmNameSignature">Full name of the used symmetric algorithm.</param>
        /// <param name="hashAlgorithmName">Name of the hash algorithm used for file signing.</param>
        /// <param name="ownerPublicKey">Users public RSA key.</param>
        public SecurityDescriptor(int ownerId, string algorithmNameSignature, string hashAlgorithmName, RSAParameters ownerPublicKey) : base(AttributeType.SECURITY_DESCRIPTOR)
        {
            OwnerId = ownerId;
            AlgorithmNameSignature = algorithmNameSignature;
            HashAlgorithmName      = hashAlgorithmName;

            var algorithm = AlgorithmUtility.GetAlgorithmFromNameSignature(AlgorithmNameSignature);

            IV = algorithm.AdditionalData;
            Users.Add(ownerId, new FileEncryptionKey(algorithm.Key).UnparseFek(ownerPublicKey));
        }
示例#3
0
        /// <summary>
        /// Encrypts original file using set parameters.
        /// </summary>
        /// <param name="originalFile">Original, unencrypted file.</param>
        /// <param name="userId">Id of the user who is encrypting original file.</param>
        /// <param name="userPrivateKey">Private RSA key of the user encrypting the file.</param>
        /// <returns>Encrypted file in its raw form.</returns>
        public byte[] Encrypt(OriginalFile originalFile, int userId, RSAParameters userPrivateKey)
        {
            // create a file signature
            SignFile(originalFile.FileContent, ref userPrivateKey);

            Headers[2] = new Data(originalFile.FileContent,
                                  AlgorithmUtility.GetAlgorithmFromNameSignature(((SecurityDescriptor)Headers[1]).AlgorithmNameSignature,
                                                                                 ((SecurityDescriptor)Headers[1]).GetKey(userId, userPrivateKey), ((SecurityDescriptor)Headers[1]).IV));

            ((StandardInformation)Headers[0]).TotalLength = (uint)((Data)Headers[2]).EncryptedData.Length;

            return(Flush());
        }
示例#4
0
        /// <summary>
        /// Decrypts encrypted file using parameters contained inside headers of the encrypted file.
        /// </summary>
        /// <param name="encryptedFile">Encrypted file in its raw form.</param>
        /// <param name="userId">Id of the user decrypting the file.</param>
        /// <param name="userPrivateKey">Private RSA key of the user decrypting the file.</param>
        /// <param name="ownerPublicKey">Public RSA key of the file owner used to verify file signature.</param>
        /// <returns>Decrypted file.</returns>
        public OriginalFile Decrypt(byte[] encryptedFile, int userId, RSAParameters userPrivateKey, RSAParameters ownerPublicKey)
        {
            var offset = 0;

            ((StandardInformation)Headers[0]).ParseStandardInformation(encryptedFile, offset);

            // update id of the user who is accessing the file
            ((StandardInformation)Headers[0]).ReadTime    = DateTime.Now;
            ((StandardInformation)Headers[0]).RTimeUserId = (uint)userId;

            offset += (int)((StandardInformation)Headers[0]).GetSaveLength();

            ((SecurityDescriptor)Headers[1]).ParseSecurityDescriptor(encryptedFile, ref offset);
            ((Data)Headers[2]).ParseData(encryptedFile, offset, (int)((StandardInformation)Headers[0]).TotalLength);

            var fileKey = ((SecurityDescriptor)Headers[1]).GetKey(userId, userPrivateKey);

            var fileName = NameDecryption(new AesAlgorithm(fileKey, ((SecurityDescriptor)Headers[1]).IV, "OFB"));

            byte[] fileContent;

            // Try to decrypt encrypted file. Exception will be thrown if Key, Iv or algorithm signature is changed.
            // Unauthorised algorithm change doesn't always have to trigger this exception and file decryption will be successful.
            // Such file will fail signature check test below.
            try
            {
                fileContent = ((Data)Headers[2]).Decrypt(AlgorithmUtility.GetAlgorithmFromNameSignature(((SecurityDescriptor)Headers[1]).AlgorithmNameSignature, fileKey, ((SecurityDescriptor)Headers[1]).IV));
            }
            catch (Exception e)
            {
                throw new CryptographicException("Unsuccessful decryption. File has been compromised.", e);
            }

            // if file signature isn't valid Exception will be thrown!
            return(CheckFileSignature(fileContent, userId, ownerPublicKey)
                ? new OriginalFile(fileContent, fileName)
                : throw new CryptographicException("File integrity has been compromised."));
        }