public static string RandomSeed(int len) { byte[] seed = new byte[len]; RNG.GetBytes(seed); return(EncodingConverter.ByteToHexBitFiddleLowercase(seed)); }
public static (byte[] pw, byte[] mk, string reqpw) CreateAuthData001(StandardNoteAPI.APIResultAuthParams apiparams, string mail, string uip) { if (apiparams.pw_func != StandardNoteAPI.PasswordFunc.pbkdf2) { throw new Exception("Unsupported pw_func: " + apiparams.pw_func); } byte[] bytes; if (apiparams.pw_alg == StandardNoteAPI.PasswordAlg.sha512) { bytes = PBKDF2.GenerateDerivedKey(apiparams.pw_key_size / 8, Encoding.UTF8.GetBytes(uip), Encoding.UTF8.GetBytes(apiparams.pw_salt), apiparams.pw_cost, PBKDF2.HMACType.SHA512); } else if (apiparams.pw_alg == StandardNoteAPI.PasswordAlg.sha512) { bytes = PBKDF2.GenerateDerivedKey(apiparams.pw_key_size / 8, Encoding.UTF8.GetBytes(uip), Encoding.UTF8.GetBytes(apiparams.pw_salt), apiparams.pw_cost, PBKDF2.HMACType.SHA512); } else { throw new Exception("Unknown pw_alg: " + apiparams.pw_alg); } var pw = bytes.Take(bytes.Length / 2).ToArray(); var mk = bytes.Skip(bytes.Length / 2).ToArray(); var reqpw = EncodingConverter.ByteToHexBitFiddleLowercase(pw); return(pw, mk, reqpw); }
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))); }
public static string SHA256Hex(string data) { using (var sha = SHA256.Create()) { var hash = sha.ComputeHash(Encoding.UTF8.GetBytes(data)); return(EncodingConverter.ByteToHexBitFiddleLowercase(hash)); } }
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)); }
public static (byte[] mk, byte[] sp, string reqpw) CreateAuthData004(StandardNoteAPI.APIResultAuthParams apiparams, string mail, string uip) { var salt = StandardNoteCrypt.SHA256Bytes(string.Join(":", apiparams.identifier, apiparams.pw_nonce)).Take(128 / 8).ToArray(); var derivedKey = ANCrypt.Argon2(Encoding.UTF8.GetBytes(uip), salt, 5, 64 * 1024, 64); var masterKey = derivedKey.Skip(00).Take(32).ToArray(); var serverPassword = derivedKey.Skip(32).Take(32).ToArray(); var requestPassword = EncodingConverter.ByteToHexBitFiddleLowercase(serverPassword); return(masterKey, serverPassword, requestPassword); }
private static string Encrypt003(string string_to_encrypt, Guid uuid, byte[] encryption_key, byte[] auth_key) { byte[] IV = new byte[128 / 8]; RNG.GetBytes(IV); var ciphertext = AESEncryption.EncryptCBC256(Encoding.UTF8.GetBytes(string_to_encrypt), encryption_key, IV); var string_to_auth = $"003:{uuid:D}:{EncodingConverter.ByteToHexBitFiddleLowercase(IV)}:{Convert.ToBase64String(ciphertext)}"; var auth_hash = EncodingConverter.ByteToHexBitFiddleLowercase(AuthSHA256(Encoding.UTF8.GetBytes(string_to_auth), auth_key)); return($"003:{auth_hash}:{uuid:D}:{EncodingConverter.ByteToHexBitFiddleLowercase(IV)}:{Convert.ToBase64String(ciphertext)}"); }
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)); }
private static EncryptResult EncryptContent003(string rawContent, Guid uuid, byte[] masterMK, byte[] masterAK) { byte[] itemKey = new byte[512 / 8]; RNG.GetBytes(itemKey); var item_ek = itemKey.Take(itemKey.Length / 2).ToArray(); var item_ak = itemKey.Skip(itemKey.Length / 2).ToArray(); var encContent = Encrypt003(rawContent, uuid, item_ek, item_ak); var encItemKey = Encrypt003(EncodingConverter.ByteToHexBitFiddleLowercase(itemKey), uuid, masterMK, masterAK); return(new EncryptResult { enc_item_key = encItemKey, enc_content = encContent, auth_hash = null, }); }
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))); }
private static EncryptResult EncryptContent001(string content, byte[] mk) { byte[] itemKey = new byte[512 / 8]; RNG.GetBytes(itemKey); var ek = itemKey.Take(itemKey.Length / 2).ToArray(); var ak = itemKey.Skip(itemKey.Length / 2).ToArray(); string encContent = "001" + Convert.ToBase64String(AESEncryption.EncryptCBC256(Encoding.UTF8.GetBytes(content), ek, null)); var authHash = EncodingConverter.ByteToHexBitFiddleLowercase(AuthSHA256(Encoding.UTF8.GetBytes(encContent), ak)); var encItemKey = Convert.ToBase64String(AESEncryption.EncryptCBC256(Encoding.UTF8.GetBytes(EncodingConverter.ByteToHexBitFiddleLowercase(itemKey)), mk, null)); return(new EncryptResult { enc_item_key = encItemKey, enc_content = encContent, auth_hash = authHash, }); }
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)); }
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)); }