private Cipher GetDecryptFn(CipherV1 cipher)
 {
     return(data => {
         var arr = data.Split('_');
         return cipher.Process(false, arr[0], arr[1]);
     });
 }
        public IList <BaseEntry> Load(Stream stream, string password)
        {
            var json = new JsonConvert();

            var reader = new StreamReader(stream);
            var backup = json.Deserialize <DeserializedBackup>(reader.ReadToEnd());

            if (!PFP_APPLICATION.Equals(backup.application))
            {
                throw new ReaderException($"Unsupported application {backup.application}");
            }

            if (!(backup.format == 2 || backup.format == 3))
            {
                throw new ReaderException($"Unsupported format version {backup.format}");
            }

            if (!(backup.data.ContainsKey(SALT_KEY) || backup.data.ContainsKey(HMAC_KEY)))
            {
                throw new ReaderException($"Invalid format");
            }

            string str;

            var hasher  = new HasherV2(password);
            var cipher  = new CipherV1(hasher.Hash, backup.data[SALT_KEY]);
            var decrypt = GetDecryptFn(cipher);

            try {
                str = decrypt(backup.data[HMAC_KEY]);
            } catch (InvalidCipherTextException e) {
                if (e.Message.Equals(MAC_MESSAGE))
                {
                    throw new ReaderException("Wrong master password");
                }
                else
                {
                    throw;
                }
            }

            backup.data.Remove(SALT_KEY);
            backup.data.Remove(HMAC_KEY);

            var result = new List <BaseEntry>();

            foreach (var item in backup.data)
            {
                if (!item.Key.StartsWith(STORAGE_PREFIX))
                {
                    continue;
                }

                str = decrypt(item.Value);
                result.Add(json.Deserialize <BaseEntry>(str));
            }

            return(result);
        }
 private Cipher GetEncryptFn(CipherV1 cipher)
 {
     return(data => {
         var iv = Util.GenerateRandom(IV_LENGTH);
         var str = cipher.Process(true, iv, data);
         return iv + "_" + str;
     });
 }
        public void Save(Stream stream, string password, IList <BaseEntry> entries)
        {
            var backup = new DeserializedBackup {
                application = PFP_APPLICATION,
                format      = 2,
                data        = new Dictionary <string, string>()
            };

            entries = Util.GenerateSiteEntries(entries);

            var salt = Util.GenerateRandom(SALT_LENGTH);
            var hmac = Util.GenerateRandom(HMAC_LENGTH);

            var json    = new JsonConvert();
            var hasher  = new HasherV2(password);
            var digest  = new DigesterV1(hmac);
            var cipher  = new CipherV1(hasher.Hash, salt);
            var encrypt = GetEncryptFn(cipher);

            backup.data.Add(SALT_KEY, salt);
            backup.data.Add(HMAC_KEY, encrypt(json.Serialize(hmac)));

            foreach (var entry in entries)
            {
                var data = encrypt(json.Serialize(entry));

                var key = STORAGE_PREFIX + digest.Digest(entry.site);

                if (entry is PassEntry pass)
                {
                    key += ":" + digest.Digest(pass.site + "\0" + pass.name + "\0" + pass.revision);
                }

                backup.data.Add(key, data);
            }

            var writer = new StreamWriter(stream);
            var str    = json.Serialize(backup);

            writer.Write(str);
            writer.Flush();
        }
示例#5
0
 static Crypto()
 {
     _dbHttpV1    = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 };
     cipherHTTPV1 = new CipherV1(_dbHttpV1);
 }