예제 #1
0
        private static string DecryptContent004(string encContent, string encItemKey, Guid?itemsKeyID, StandardNoteData dat)
        {
            StandardNoteAPI.Logger.TraceExt(StandardNotePlugin.Name, "Decrypt content with schema [002]",
                                            ("encContent", encContent),
                                            ("encItemKey", encItemKey),
                                            ("itemsKeyID", itemsKeyID?.ToString() ?? "NULL"));

            var keyOuter = dat.SessionData.RootKey_MasterKey;

            if (itemsKeyID != null)
            {
                var itemskey = dat.ItemsKeys.FirstOrDefault(p => p.UUID == itemsKeyID);
                if (itemskey == null)
                {
                    throw new StandardNoteAPIException($"Could not decrypt item (Key {itemsKeyID} not found)");
                }

                StandardNoteAPI.Logger.TraceExt(StandardNotePlugin.Name, $"Found itemskey: {itemskey.UUID}",
                                                ("itemskey.IsDefault", itemskey.IsDefault.ToString()),
                                                ("itemskey.Version", itemskey.Version),
                                                ("itemskey.Key", EncodingConverter.ByteToHexBitFiddleLowercase(itemskey.Key)));

                keyOuter = itemskey.Key;
            }

            var keyInner = Decrypt004(encItemKey, keyOuter);

            return(Decrypt004(encContent, EncodingConverter.StringToByteArrayCaseInsensitive(keyInner)));
        }
예제 #2
0
        private static string DecryptContent002(string encContent, string encItemKey, byte[] masterMK, byte[] masterAK)
        {
            var item_key = Decrypt002(encItemKey, masterMK, masterAK);

            var item_ek = item_key.Substring(0, item_key.Length / 2);
            var item_ak = item_key.Substring(item_key.Length / 2, item_key.Length / 2);

            return(Decrypt002(encContent, EncodingConverter.StringToByteArrayCaseInsensitive(item_ek), EncodingConverter.StringToByteArrayCaseInsensitive(item_ak)));
        }
예제 #3
0
        private static string DecryptContent001(string encContent, string encItemKey, string authHash, StandardNoteData dat)
        {
            StandardNoteAPI.Logger.TraceExt(StandardNotePlugin.Name, "Decrypt content with schema [001]",
                                            ("encContent", encContent),
                                            ("encItemKey", encItemKey),
                                            ("authHash", authHash));

            byte[] masterkey;

            if (dat.SessionData.Version == "001" || dat.SessionData.Version == "002" || dat.SessionData.Version == "003")
            {
                masterkey = dat.SessionData.RootKey_MasterKey;

                StandardNoteAPI.Logger.Trace(StandardNotePlugin.Name, "Use masterkey from session");
            }
            else
            {
                var itemskey = dat.ItemsKeys.FirstOrDefault(p => p.Version == "001");
                if (itemskey == null)
                {
                    throw new StandardNoteAPIException($"Could not decrypt item (Key for 002 not found)");
                }

                StandardNoteAPI.Logger.TraceExt(StandardNotePlugin.Name, $"Found itemskey: {itemskey.UUID}",
                                                ("itemskey.IsDefault", itemskey.IsDefault.ToString()),
                                                ("itemskey.Version", itemskey.Version),
                                                ("itemskey.Key", EncodingConverter.ByteToHexBitFiddleLowercase(itemskey.Key)),
                                                ("itemskey.AuthKey", EncodingConverter.ByteToHexBitFiddleLowercase(itemskey.AuthKey)));

                masterkey = itemskey.Key;
            }

            var itemKey = EncodingConverter.StringToByteArrayCaseInsensitive(Encoding.ASCII.GetString(AESEncryption.DecryptCBC256(Convert.FromBase64String(encItemKey), masterkey, new byte[16])));

            var ek = itemKey.Take(itemKey.Length / 2).ToArray();
            var ak = itemKey.Skip(itemKey.Length / 2).ToArray();

            var realHash = EncodingConverter.ByteToHexBitFiddleLowercase(AuthSHA256(Encoding.UTF8.GetBytes(encContent), ak));

            if (authHash == null)
            {
                throw new ArgumentNullException(nameof(authHash));
            }
            if (realHash.ToLower() != authHash.ToLower())
            {
                throw new StandardNoteAPIException("Decrypting content failed - hash mismatch");
            }

            var c = AESEncryption.DecryptCBC256(Convert.FromBase64String(encContent.Substring(3)), ek, null);

            return(Encoding.UTF8.GetString(c));
        }
예제 #4
0
        private static string Decrypt004(string encContent, byte[] key)
        {
            var split = encContent.Split(':');

            var version            = split[0];
            var nonce              = EncodingConverter.StringToByteArrayCaseInsensitive(split[1]);
            var ciphertext         = Convert.FromBase64String(split[2]);
            var authenticated_data = Encoding.UTF8.GetBytes(split[3]);

            if (version != "004")
            {
                throw new StandardNoteAPIException($"Version must be 004 to decrypt 004 encrypted item (duh.)");
            }

            var plain = ANCrypt.XChaCha20Decrypt(ciphertext, nonce, key, authenticated_data);

            return(Encoding.UTF8.GetString(plain));
        }
예제 #5
0
        public static StandardFileItemsKey Deserialize(XElement e)
        {
            var id      = XHelper.GetAttributeGuid(e, "ID");
            var version = XHelper.GetAttributeString(e, "Version");
            var defKey  = XHelper.GetAttributeBool(e, "Default");
            var cdate   = XHelper.GetAttributeDateTimeOffsetOrDefault(e, "CreationDate", DateTimeOffset.MinValue);
            var mdate   = XHelper.GetAttributeDateTimeOffsetOrDefault(e, "ModificationDate", DateTimeOffset.Now);
            var appdata = XHelper.GetAttributeString(e, "AppData");
            var key     = EncodingConverter.StringToByteArrayCaseInsensitive(e.Value);
            var authkey = EncodingConverter.StringToByteArrayCaseInsensitive(XHelper.GetAttributeStringOrDefault(e, "AuthKey", ""));

            if (authkey.Length == 0)
            {
                authkey = null;
            }

            return(new StandardFileItemsKey(id, version, cdate, mdate, key, authkey, defKey, appdata));
        }
예제 #6
0
        private static string DecryptContent001(string encContent, string encItemKey, string authHash, byte[] masterkey)
        {
            var itemKey = EncodingConverter.StringToByteArrayCaseInsensitive(Encoding.ASCII.GetString(AESEncryption.DecryptCBC256(Convert.FromBase64String(encItemKey), masterkey, new byte[16])));

            var ek = itemKey.Take(itemKey.Length / 2).ToArray();
            var ak = itemKey.Skip(itemKey.Length / 2).ToArray();

            var realHash = EncodingConverter.ByteToHexBitFiddleLowercase(AuthSHA256(Encoding.UTF8.GetBytes(encContent), ak));

            if (realHash.ToLower() != authHash.ToLower())
            {
                throw new StandardNoteAPIException("Decrypting content failed - hash mismatch");
            }

            var c = AESEncryption.DecryptCBC256(Convert.FromBase64String(encContent.Substring(3)), ek, null);

            return(Encoding.UTF8.GetString(c));
        }
예제 #7
0
        private static EncryptResult EncryptContent004(string rawContent, Guid uuid, StandardNoteData dat)
        {
            var item_key           = RandomSeed(32);
            var authenticated_data = $"{{\"u\":\"{uuid:D}\",\"v\":\"004\"}}";

            var encrypted_content = Encrypt004(rawContent, EncodingConverter.StringToByteArrayCaseInsensitive(item_key), authenticated_data);

            var default_items_key = GetDefaultItemsKey(dat, "004");

            var enc_item_key = Encrypt004(item_key, default_items_key.Key, authenticated_data);

            return(new EncryptResult
            {
                enc_item_key = enc_item_key,
                enc_content = encrypted_content,
                auth_hash = null,
                items_key_id = default_items_key.UUID,
            });
        }
예제 #8
0
        private static string DecryptContent003(string encContent, string encItemKey, StandardNoteData dat)
        {
            StandardNoteAPI.Logger.TraceExt(StandardNotePlugin.Name, "Decrypt content with schema [002]",
                                            ("encContent", encContent),
                                            ("encItemKey", encItemKey));

            byte[] masterMK;
            byte[] masterAK;

            if (dat.SessionData.Version == "001" || dat.SessionData.Version == "002" || dat.SessionData.Version == "003")
            {
                masterMK = dat.SessionData.RootKey_MasterKey;
                masterAK = dat.SessionData.RootKey_MasterAuthKey;

                StandardNoteAPI.Logger.Trace(StandardNotePlugin.Name, "Use key/authkey from session");
            }
            else
            {
                var itemskey = dat.ItemsKeys.FirstOrDefault(p => p.Version == "003");
                if (itemskey == null)
                {
                    throw new StandardNoteAPIException($"Could not decrypt item (Key for 002 not found)");
                }

                StandardNoteAPI.Logger.TraceExt(StandardNotePlugin.Name, $"Found itemskey: {itemskey.UUID}",
                                                ("itemskey.IsDefault", itemskey.IsDefault.ToString()),
                                                ("itemskey.Version", itemskey.Version),
                                                ("itemskey.Key", EncodingConverter.ByteToHexBitFiddleLowercase(itemskey.Key)),
                                                ("itemskey.AuthKey", EncodingConverter.ByteToHexBitFiddleLowercase(itemskey.AuthKey)));

                masterMK = itemskey.Key;
                masterAK = itemskey.AuthKey;
            }

            var item_key = Decrypt003(encItemKey, masterMK, masterAK);

            StandardNoteAPI.Logger.Trace(StandardNotePlugin.Name, "item_key decrypted", $"item_key := '{item_key}'");

            var item_ek = item_key.Substring(0, item_key.Length / 2);
            var item_ak = item_key.Substring(item_key.Length / 2, item_key.Length / 2);

            return(Decrypt003(encContent, EncodingConverter.StringToByteArrayCaseInsensitive(item_ek), EncodingConverter.StringToByteArrayCaseInsensitive(item_ak)));
        }
예제 #9
0
        private static string Encrypt004(string content, byte[] key, string assocData)
        {
            var nonce = RandomSeed(24);

            var authenticated_data = Convert.ToBase64String(Encoding.UTF8.GetBytes(assocData));

            var ciphertext = ANCrypt.XChaCha20Encrypt(Encoding.UTF8.GetBytes(content), EncodingConverter.StringToByteArrayCaseInsensitive(nonce), key, Encoding.UTF8.GetBytes(authenticated_data));

            return(string.Join(":", "004", nonce, Convert.ToBase64String(ciphertext), authenticated_data));
        }
예제 #10
0
        private static string Decrypt003(string string_to_decrypt, byte[] encryption_key, byte[] auth_key)
        {
            var components = string_to_decrypt.Split(':');
            var version    = components[0];
            var auth_hash  = components[1];
            var uuid       = components[2];
            var IV         = components[3];
            var ciphertext = components[4];

            if (auth_key != null && auth_key.Length > 0)
            {
                var string_to_auth  = $"{version}:{uuid}:{IV}:{ciphertext}";
                var local_auth_hash = EncodingConverter.ByteToHexBitFiddleLowercase(AuthSHA256(Encoding.UTF8.GetBytes(string_to_auth), auth_key));

                if (local_auth_hash.ToUpper() != auth_hash.ToUpper())
                {
                    StandardNoteAPI.Logger.Warn(StandardNotePlugin.Name, "AuthHash verification failed",
                                                $"local_auth_hash := '{local_auth_hash}'\nauth_hash := '{auth_hash}'");

                    throw new Exception("Item auth-hash mismatch");
                }
                else
                {
                    StandardNoteAPI.Logger.TraceExt(StandardNotePlugin.Name, "AuthHash verified",
                                                    ("local_auth_hash", local_auth_hash),
                                                    ("auth_hash", auth_hash));
                }
            }
            else
            {
                StandardNoteAPI.Logger.Warn(StandardNotePlugin.Name, "AuthHash verification skipped (no auth_key)");
            }

            var result = AESEncryption.DecryptCBC256(Convert.FromBase64String(ciphertext), encryption_key, EncodingConverter.StringToByteArrayCaseInsensitive(IV));

            return(Encoding.UTF8.GetString(result));
        }
예제 #11
0
        private static string Decrypt003(string string_to_decrypt, byte[] encryption_key, byte[] auth_key)
        {
            var components = string_to_decrypt.Split(':');
            var version    = components[0];
            var auth_hash  = components[1];
            var uuid       = components[2];
            var IV         = components[3];
            var ciphertext = components[4];

            if (auth_key != null && auth_key.Length > 0)
            {
                var string_to_auth  = $"{version}:{uuid}:{IV}:{ciphertext}";
                var local_auth_hash = EncodingConverter.ByteToHexBitFiddleLowercase(AuthSHA256(Encoding.UTF8.GetBytes(string_to_auth), auth_key));
                if (local_auth_hash.ToUpper() != auth_hash.ToUpper())
                {
                    throw new Exception("Item auth-hash mismatch");
                }
            }

            var result = AESEncryption.DecryptCBC256(Convert.FromBase64String(ciphertext), encryption_key, EncodingConverter.StringToByteArrayCaseInsensitive(IV));

            return(Encoding.UTF8.GetString(result));
        }