I am attempting to read the encrypted values of cookies using a C# console app.
My cookie reader class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using Microsoft.EntityFrameworkCore;
namespace ConsoleApp1.Models
{
public class ChromeCookieReader
{
public IEnumerable<Tuple<string, string>> ReadCookies(string hostName)
{
if (hostName == null) throw new ArgumentNullException("hostName");
using var context = new ChromeCookieDbContext();
var cookies = context
.Cookies
.Where(c => c.HostKey.Equals("localhost"))
.AsNoTracking();
foreach (var cookie in cookies)
{
var decodedData = ProtectedData
.Unprotect(cookie.EncryptedValue,
null,
DataProtectionScope.CurrentUser);
var decodedValue = Encoding.UTF8.GetString(decodedData);
yield return Tuple.Create(cookie.Name, decodedValue);
}
}
}
}
My EF DbContext
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
using Microsoft.EntityFrameworkCore;
namespace ConsoleApp1.Models
{
public class Cookie
{
[Column("host_key")]
public string HostKey { get; set; }
[Column("name")]
public string Name { get; set; }
[Column("encrypted_value")]
public byte[] EncryptedValue { get; set; }
}
public class ChromeCookieDbContext : DbContext
{
public DbSet<Cookie> Cookies { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// var dbPath = Environment.GetFolderPath(
// Environment.SpecialFolder.LocalApplicationData)
// + @"\Google\Chrome\User Data\Default\Cookies";
var dbPath = Environment.GetFolderPath(
Environment.SpecialFolder.LocalApplicationData)
+ @"\BraveSoftware\Brave-Browser\User Data\Default\Cookies";
if (!System.IO.File.Exists(dbPath)) throw new System.IO.FileNotFoundException("Cant find cookie store", dbPath); // race condition, but i'll risk it
var connectionString = "Data Source=" + dbPath + ";Mode=ReadOnly;";
optionsBuilder
.UseSqlite(connectionString);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Cookie>().ToTable("cookies").HasNoKey();
}
}
}
My attempted solution was inspired by Encrypted cookies in Chrome however it doesn't look like it'll work the same despite Brave Browser being based on Chromium. Instead the Windows Data Protection API throws an exception.
Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException
HResult=0x0000000D
Message=The data is invalid.
Source=System.Security.Cryptography.ProtectedData
StackTrace:
at System.Security.Cryptography.ProtectedData.ProtectOrUnprotect(Byte[] inputData, Byte[] optionalEntropy, DataProtectionScope scope, Boolean protect)
at System.Security.Cryptography.ProtectedData.Unprotect(Byte[] encryptedData, Byte[] optionalEntropy, DataProtectionScope scope)
at ConsoleApp1.Models.ChromeCookieReader.<ReadCookies>d__0.MoveNext()
Other known issues: If Brave is open EF Core "freaks out" that the SQLite database is locked and won't read anything.