Всем здорова работяги, такая херня появилась дней 15 назад что куки приходят с карокозябрами, и спереди стоит V10. У кого как *******ы работают с куками на с#? Обновы DecryptAPI не где не нашел. Firefox приходит нормально. Кодировка стоит UTF-8.
public static class Chromium { public enum Browser { Opera, Brave } public static IEnumerable<Cookie> ReadCookies(string path, Browser browser) { const int macBitSize = 128; const int nonceBitSize = 96; var destFile = Path.Combine(Path.GetTempPath() + "cck"); File.Copy(Path.Combine(path, "Cookies"), destFile, true); using var cnn = new SQLiteConnection($"Data Source={destFile};pooling=false"); cnn.Open(); using var cmd = new SQLiteCommand("select * from cookies", cnn); using var rdr = cmd.ExecuteReader(); var lsPath = browser switch { Browser.Opera => Path.Combine(path, "Local State"), Browser.Brave => Path.Combine( new DirectoryInfo(path).Parent?.FullName ?? throw new ArgumentException("Path is broken/too short", nameof(path)), "Local State"), _ => "" }; var encKey = File.ReadAllText(lsPath); encKey = JObject.Parse(encKey)["os_crypt"]?["encrypted_key"]?.ToString(); if (encKey != null) { var decodedKey = ProtectedData.Unprotect(Convert.FromBase64String(encKey).Skip(5).ToArray(), null, DataProtectionScope.LocalMachine); var cipher = new GcmBlockCipher(new AesEngine()); while (rdr.Read()) { var encryptedData = (byte[]) rdr["encrypted_value"]; using var cipherStream = new MemoryStream(encryptedData); using var cipherReader = new BinaryReader(cipherStream); cipherReader.ReadBytes(3); var nonce = cipherReader.ReadBytes(nonceBitSize / 8); var parameters = new AeadParameters(new KeyParameter(decodedKey), macBitSize, nonce); cipher.Init(false, parameters); var cipherText = cipherReader.ReadBytes(encryptedData.Length); var plainText = new byte[cipher.GetOutputSize(cipherText.Length)]; var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0); cipher.DoFinal(plainText, len); yield return new Cookie((string) rdr["host_key"], (string) rdr["name"], Encoding.Default.GetString(plainText), (string) rdr["path"], ToDateTime((long) rdr["expires_utc"]), (long) rdr["is_secure"] == 1, (long) rdr["is_httponly"] == 1, (long)rdr["samesite"]); } } cmd.Dispose(); rdr.Close(); cnn.Close(); File.Delete(destFile); } private static DateTime ToDateTime(long unixTimeStamp) { try { return unixTimeStamp > 253402300799 ? DateTimeOffset.FromUnixTimeMilliseconds(unixTimeStamp).UtcDateTime : DateTimeOffset.FromUnixTimeSeconds(unixTimeStamp).UtcDateTime; } catch { return DateTime.Now + TimeSpan.FromDays(365 * 3); } } public record Cookie(string Host, string Name, string Value, string Path, DateTime Expiries, bool IsSecure, bool IsHttpOnly, long Samesite); } public static class Converters { private static Cookie ToSystemCookie(this Chromium.Cookie cookie) { return new Cookie { HttpOnly = cookie.IsHttpOnly, Secure = cookie.IsSecure, Expires = cookie.Expiries, Expired = cookie.Expiries < DateTime.Now, Path = cookie.Path, Value = cookie.Value, Name = !string.IsNullOrEmpty(cookie.Name) ? cookie.Name : "nullname", Domain = cookie.Host }; } public static IEnumerable<Cookie> ToSystemCookies(this IEnumerable<Chromium.Cookie> cookies) { return cookies.Select(cookie => cookie.ToSystemCookie()); } } C# public static class Chromium { public enum Browser { Opera, Brave } public static IEnumerable<Cookie> ReadCookies(string path, Browser browser) { const int macBitSize = 128; const int nonceBitSize = 96; var destFile = Path.Combine(Path.GetTempPath() + "cck"); File.Copy(Path.Combine(path, "Cookies"), destFile, true); using var cnn = new SQLiteConnection($"Data Source={destFile};pooling=false"); cnn.Open(); using var cmd = new SQLiteCommand("select * from cookies", cnn); using var rdr = cmd.ExecuteReader(); var lsPath = browser switch { Browser.Opera => Path.Combine(path, "Local State"), Browser.Brave => Path.Combine( new DirectoryInfo(path).Parent?.FullName ?? throw new ArgumentException("Path is broken/too short", nameof(path)), "Local State"), _ => "" }; var encKey = File.ReadAllText(lsPath); encKey = JObject.Parse(encKey)["os_crypt"]?["encrypted_key"]?.ToString(); if (encKey != null) { var decodedKey = ProtectedData.Unprotect(Convert.FromBase64String(encKey).Skip(5).ToArray(), null, DataProtectionScope.LocalMachine); var cipher = new GcmBlockCipher(new AesEngine()); while (rdr.Read()) { var encryptedData = (byte[]) rdr["encrypted_value"]; using var cipherStream = new MemoryStream(encryptedData); using var cipherReader = new BinaryReader(cipherStream); cipherReader.ReadBytes(3); var nonce = cipherReader.ReadBytes(nonceBitSize / 8); var parameters = new AeadParameters(new KeyParameter(decodedKey), macBitSize, nonce); cipher.Init(false, parameters); var cipherText = cipherReader.ReadBytes(encryptedData.Length); var plainText = new byte[cipher.GetOutputSize(cipherText.Length)]; var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0); cipher.DoFinal(plainText, len); yield return new Cookie((string) rdr["host_key"], (string) rdr["name"], Encoding.Default.GetString(plainText), (string) rdr["path"], ToDateTime((long) rdr["expires_utc"]), (long) rdr["is_secure"] == 1, (long) rdr["is_httponly"] == 1, (long)rdr["samesite"]); } } cmd.Dispose(); rdr.Close(); cnn.Close(); File.Delete(destFile); } private static DateTime ToDateTime(long unixTimeStamp) { try { return unixTimeStamp > 253402300799 ? DateTimeOffset.FromUnixTimeMilliseconds(unixTimeStamp).UtcDateTime : DateTimeOffset.FromUnixTimeSeconds(unixTimeStamp).UtcDateTime; } catch { return DateTime.Now + TimeSpan.FromDays(365 * 3); } } public record Cookie(string Host, string Name, string Value, string Path, DateTime Expiries, bool IsSecure, bool IsHttpOnly, long Samesite); } public static class Converters { private static Cookie ToSystemCookie(this Chromium.Cookie cookie) { return new Cookie { HttpOnly = cookie.IsHttpOnly, Secure = cookie.IsSecure, Expires = cookie.Expiries, Expired = cookie.Expiries < DateTime.Now, Path = cookie.Path, Value = cookie.Value, Name = !string.IsNullOrEmpty(cookie.Name) ? cookie.Name : "nullname", Domain = cookie.Host }; } public static IEnumerable<Cookie> ToSystemCookies(this IEnumerable<Chromium.Cookie> cookies) { return cookies.Select(cookie => cookie.ToSystemCookie()); } } Пример вызова: Chromium .ReadCookies(@"c:\Users\Kirill\AppData\Local\BraveSoftware\Brave-Browser-Nightly\User Data\Default\", Chromium.Browser.Brave)