Пример #1
0
        /// <summary>
        /// writes the given data in the PrivateNotes-crypt-format to the harddrive
        /// </summary>
        /// <param name="_filename"></param>
        /// <param name="_content"></param>
        /// <param name="_key"></param>
        /// <returns></returns>
        public bool WriteCompatibleFile(String _filename, byte[] _content, byte[] _key, byte[] _salt)
        {
            Console.WriteLine("writing " + _filename);

            byte[] paddedContent = Util.padWithLengthInfo(_content, 16);


            byte[] doubleHashedKey = AESUtil.CalculateSaltedHash(_key, _salt);

            Util.AssureFileExists(_filename);
            FileStream fout = new FileStream(_filename, FileMode.Truncate, FileAccess.Write);

            byte[] version = System.BitConverter.GetBytes(CRYPTO_VERSION);

            long now = Util.ConvertToUnixTimestamp(DateTime.Now.ToUniversalTime());

            Console.WriteLine("long value: " + now);
            byte[] dateTime = System.BitConverter.GetBytes(now);

            // calculate check-hash (to verify nothing has been altered)
            MemoryStream membuf = new MemoryStream();

            byte[] fileNameBytes = Util.GetBytes(Path.GetFileName(_filename));
            membuf.Write(version, 0, version.Length);
            membuf.Write(dateTime, 0, dateTime.Length);
            membuf.Write(fileNameBytes, 0, fileNameBytes.Length);
            membuf.Write(paddedContent, 0, paddedContent.Length);
            byte[] dataHashValue = AESUtil.CalculateHash(membuf.ToArray());

            MemoryStream cryptMe = new MemoryStream();

            cryptMe.Write(dataHashValue, 0, dataHashValue.Length);
            cryptMe.Write(paddedContent, 0, paddedContent.Length);

            byte[] cryptedData = AESUtil.Encrypt(_key, cryptMe.ToArray());

            fout.Write(version, 0, version.Length);
            fout.Write(dateTime, 0, dateTime.Length);
            fout.Write(doubleHashedKey, 0, doubleHashedKey.Length);
            fout.Write(_salt, 0, _salt.Length);
            fout.Write(cryptedData, 0, cryptedData.Length);
            fout.Close();

            Console.WriteLine("wrote file");
            return(true);
        }
Пример #2
0
        public byte[] DecryptFromStream(String _filename, Stream fin, byte[] _key, out bool _wasOk)
        {
            _wasOk = false;
            Console.WriteLine();
            Console.WriteLine("checking " + _filename);

            byte[]       version        = new byte[2];
            byte[]       datetime       = new byte[8];
            byte[]       keyVerifyValue = new byte[32];
            byte[]       keySaltValue   = new byte[32];
            byte[]       dataHashValue  = new byte[32];
            byte[]       cryptedData    = null;
            MemoryStream membuf         = new MemoryStream();

            if (fin.Read(version, 0, version.Length) != version.Length)
            {
                throw new FormatException("file seems to be corrupt (version)");
            }
            if (fin.Read(datetime, 0, datetime.Length) != datetime.Length)
            {
                throw new FormatException("file seems to be corrupt (date)");
            }
            if (fin.Read(keyVerifyValue, 0, keyVerifyValue.Length) != keyVerifyValue.Length)
            {
                throw new FormatException("file seems to be corrupt (keyVerify)");
            }
            if (fin.Read(keySaltValue, 0, keySaltValue.Length) != keySaltValue.Length)
            {
                throw new FormatException("file seems to be corrupt (keySalt)");
            }

            byte[] singleHashedKey = AESUtil.CalculateSaltedHash(_key, keySaltValue);
            byte[] doubleHashedKey = AESUtil.CalculateSaltedHash(singleHashedKey, keySaltValue);

            if (System.BitConverter.ToUInt16(version, 0) != CRYPTO_VERSION)
            {
                throw new EncryptionException("Wrong Version");
            }

            if (!Util.ArraysAreEqual(keyVerifyValue, doubleHashedKey))
            {
                throw new PasswordException("Wrong Password");
            }

            // read rest of file (encrypted data)
            int data = fin.ReadByte();

            while (data >= 0)
            {
                membuf.WriteByte((byte)data);
                data = fin.ReadByte();
            }
            cryptedData = membuf.ToArray();

            // build data that should be in hash
            membuf = new MemoryStream();
            // filename (without path) as byte[]
            byte[] fileNameBytes = Util.GetBytes(Path.GetFileName(_filename));

            byte[] realData = null;
            {
                byte[] decryptedData = AESUtil.Decrypt(singleHashedKey, cryptedData);
                // get first 32 bytes of decrypted data, this is the control-hash (dataHashValue)
                System.Array.Copy(decryptedData, dataHashValue, dataHashValue.Length);

                byte[] otherData = new byte[decryptedData.Length - dataHashValue.Length];
                System.Array.Copy(decryptedData, dataHashValue.Length, otherData, 0, otherData.Length);
                realData = Util.getDataFromPaddedWithLengthInfo(otherData);

                // write things that are used for the verification-hash into the membuf buffer
                membuf.Write(version, 0, version.Length);
                membuf.Write(datetime, 0, datetime.Length);
                membuf.Write(fileNameBytes, 0, fileNameBytes.Length);
                membuf.Write(otherData, 0, otherData.Length);
            }

            byte[] dataToHash        = membuf.ToArray();
            byte[] dataHashToCompare = AESUtil.CalculateHash(dataToHash);
            if (!Util.ArraysAreEqual(dataHashValue, dataHashToCompare))
            {
                Console.WriteLine("Hashes don't match!!!! Data may have been manipulated!");
                return(null);
            }

            long     fileDate    = System.BitConverter.ToInt64(datetime, 0);
            DateTime dateTimeObj = Util.ConvertFromUnixTimestamp(fileDate);

            dateTimeObj = dateTimeObj.ToLocalTime();             // because it's stored in utc
            Console.WriteLine("data seems ok, file is from " + dateTimeObj.ToShortDateString() + " " + dateTimeObj.ToShortTimeString());
            Console.WriteLine("note data:");
            Console.WriteLine(Util.FromBytes(realData));
            Console.WriteLine("-=END OF NOTE=-");

            _wasOk = true;
            return(realData);
        }