Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
771 views
in Technique[技术] by (71.8m points)

sqlite - Reading and Inserting Chrome Cookies Java

This is actually exactly what I am looking for but in Java:

Encrypted cookies in Chrome

The mentioned "Windows Data Protection API (DPAPI)" I have found here for Java:

http://jdpapi.sourceforge.net/

but its "outdated" or only for 32bit platform.

SQLite connection and result is of course working that's what I got atm:

public void getDecryptedValue() {
    try {
        Statement stmt = connection.createStatement();
        String sql = "SELECT * FROM cookies";
        ResultSet rs = stmt.executeQuery(sql);

        int cookieCount = 1;
        while (rs.next()) {
            log.debug("####### Cookie " + cookieCount + " ############");
            String host_key = rs.getString("host_key");
            log.debug(host_key);

            byte[] encrypted_value = rs.getBytes("encrypted_value");

            //this ofc outputs "nonsense". here the decryption is needed.
            log.debug(encrypted_value.toString()); 

            cookieCount++;
        }
        rs.close();
        stmt.close();

    } catch (SQLException e) {
        e.printStackTrace();
    }
}

I searched now for 2 days found nothing helpful my next approach would be to decrypt/encrypt triple DES encryption with (Windows username? and password? what is used as seed if you have no password?) but I really don't know how I should do that with the BLOB I get from the SQLite DB or even start.

Edit: I am digging deeper with that atm : http://n8henrie.com/2014/05/decrypt-chrome-cookies-with-python/

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I spent a long time on this myself. Here are some classes you can use to decrypt cookies for Chrome on Mac, Windows, and Linux. I didn't implement inserting cookies, but I imagine you have most of everything you need with this code to add that functionality.

It requires some third party libraries (JNI Windows encryption wrappers and SQLite) so I am linking to the Maven project I am using the code in if you need to see the code in context.

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

import com.sun.jna.platform.win32.Crypt32Util;

public class Test {

    public static void main(String[] args) throws IOException {
        ChromeBrowser chrome = new ChromeBrowser();
        Set<Cookie> cookies = chrome.getCookiesForDomain("stackoverflow.com");
        for(Cookie cookie : cookies){
            System.out.println(cookie.toString());
        }
    }

    public static abstract class Cookie {

        protected String name;
        protected byte[] encryptedValue;
        protected Date expires;
        protected String path;
        protected String domain;
        protected boolean secure;
        protected boolean httpOnly;
        protected File cookieStore;

        public Cookie(String name, byte[] encryptedValue, Date expires, String path, String domain, boolean secure, boolean httpOnly, File cookieStore) {
            this.name = name;
            this.encryptedValue = encryptedValue;
            this.expires = expires;
            this.path = path;
            this.domain = domain;
            this.secure = secure;
            this.httpOnly = httpOnly;
            this.cookieStore = cookieStore;
        }

        public String getName() {
            return name;
        }

        public byte[] getEncryptedValue() {
            return encryptedValue;
        }

        public Date getExpires() {
            return expires;
        }

        public String getPath() {
            return path;
        }

        public String getDomain() {
            return domain;
        }

        public boolean isSecure() {
            return secure;
        }

        public boolean isHttpOnly() {
            return httpOnly;
        }

        public File getCookieStore(){
            return cookieStore;
        }

        public abstract boolean isDecrypted();

    }

    public static class DecryptedCookie extends Cookie {

        private String decryptedValue;

        public DecryptedCookie(String name, byte[] encryptedValue, String decryptedValue, Date expires, String path, String domain, boolean secure, boolean httpOnly, File cookieStore) {
            super(name, encryptedValue, expires, path, domain, secure, httpOnly, cookieStore);
            this.decryptedValue = decryptedValue;
        }

        public String getDecryptedValue(){
            return decryptedValue;
        }

        @Override
        public boolean isDecrypted() {
            return true;
        }

        @Override
        public String toString() {
            return "Cookie [name=" + name + ", value=" + decryptedValue + "]";
        }

    }

    public static class EncryptedCookie extends Cookie {

        public EncryptedCookie(String name, byte[] encryptedValue, Date expires, String path, String domain, boolean secure, boolean httpOnly, File cookieStore) {
            super(name, encryptedValue, expires, path, domain, secure, httpOnly, cookieStore);
        }

        @Override
        public boolean isDecrypted() {
            return false;
        }

        @Override
        public String toString() {
            return "Cookie [name=" + name + " (encrypted)]";
        }

    }

    public static class OS {

        public static String getOsArchitecture() {
            return System.getProperty("os.arch");
        }

        public static String getOperatingSystem() {
            return System.getProperty("os.name");
        }

        public static String getOperatingSystemVersion() {
            return System.getProperty("os.version");
        }

        public static String getIP() throws UnknownHostException {
            InetAddress ip = InetAddress.getLocalHost();
            return ip.getHostAddress();
        }

        public static String getHostname() throws UnknownHostException {
            return InetAddress.getLocalHost().getHostName(); 
        }

        public static boolean isWindows() {
            return (getOperatingSystem().toLowerCase().indexOf("win") >= 0);
        }

        public static boolean isMac() {
            return (getOperatingSystem().toLowerCase().indexOf("mac") >= 0);
        }

        public static boolean isLinux() {
            return (getOperatingSystem().toLowerCase().indexOf("nix") >= 0 || getOperatingSystem().toLowerCase().indexOf("nux") >= 0 || getOperatingSystem().toLowerCase().indexOf("aix") > 0 );
        }

        public static boolean isSolaris() {
            return (getOperatingSystem().toLowerCase().indexOf("sunos") >= 0);
        }

    }

    public static abstract class Browser {

        /**
         * A file that should be used to make a temporary copy of the browser's cookie store
         */
        protected File cookieStoreCopy = new File(".cookies.db");

        /**
         * Returns all cookies
         */
        public Set<Cookie> getCookies() {
            HashSet<Cookie> cookies = new HashSet<Cookie>();
            for(File cookieStore : getCookieStores()){
                cookies.addAll(processCookies(cookieStore, null));
            }
            return cookies;
        }

        /**
         * Returns cookies for a given domain
         */
        public Set<Cookie> getCookiesForDomain(String domain) {
            HashSet<Cookie> cookies = new HashSet<Cookie>();
            for(File cookieStore : getCookieStores()){
                cookies.addAll(processCookies(cookieStore, domain));
            }
            return cookies;
        }

        /**
         * Returns a set of cookie store locations
         * @return
         */
        protected abstract Set<File> getCookieStores();

        /**
         * Processes all cookies in the cookie store for a given domain or all
         * domains if domainFilter is null
         * 
         * @param cookieStore
         * @param domainFilter
         * @return
         */
        protected abstract Set<Cookie> processCookies(File cookieStore, String domainFilter);

        /**
         * Decrypts an encrypted cookie
         * @param encryptedCookie
         * @return
         */
        protected abstract DecryptedCookie decrypt(EncryptedCookie encryptedCookie);

    }

    /**
     * An implementation of Chrome cookie decryption logic for Mac, Windows, and Linux installs 
     * 
     * References: 
     * 1) http://n8henrie.com/2014/05/decrypt-chrome-cookies-with-python/
     * 2) https://github.com/markushuber/ssnoob
     * 
     * @author Ben Holland
     */
    public static class ChromeBrowser extends Browser {

        private String chromeKeyringPassword = null;

        /**
         * Returns a set of cookie store locations
         * @return
         */
        @Override
        protected Set<File> getCookieStores() {
            HashSet<File> cookieStores = new HashSet<File>();

            // pre Win7
            cookieStores.add(new File(System.getProperty("user.home") + "\Application Data\Google\Chrome\User Data\Default\Cookies"));

            // Win 7+
            cookieStores.add(new File(System.getProperty("user.home") + "\AppData\Local\Google\Chrome\User Data\Default\Cookies"));

            // Mac
            cookieStores.add(new File(System.getProperty("user.home") + "/Library/Application Support/Google/Chrome/Default/Cookies"));

            // Linux
            cookieStores.add(new File(System.getProperty("user.home") + "/.config/chromium/Default/Cookies"));

            return cookieStores;
        }

        /**
         * Processes all cookies in the cookie store for a given domain or all
         * domains if domainFilter is null
         * 
         * @param cookieStore
         * @param domainFilter
         * @return
         */
        @Override
        protected Set<Cookie> processCookies(File cookieStore, String domainFilter) {
            HashSet<Cookie> cookies = new HashSet<Cookie>();
            if(cookieStore.exists()){
                Connection connection = null;
                try {
                    cookieStoreCopy.delete();
                    Files.copy(cookieStore.toPath(), cookieStoreCopy.toPath());
                    // load the sqlite-JDBC driver using the current class loader
                    Class.forName("org.sqlite.JDBC");
                    // create a database connection
                    connection = DriverManager.getConnection("jdbc:sqlite:" + cookieStoreCopy.getAbsolutePath());
                    Statement statement = connection.createStatement();
                    statement.setQueryTimeout(30); // set timeout to 30 seconds
                    ResultSet result = null;
                    if(domainFilter == null || domainFilter.isEmpty()){
                        result = statement.executeQuery("select * from cookies");
                    } else {
                        result = statement.executeQuery("select * from cookies where host_key like "%" + domainFilter + "%"");
                    }
                    while (result.next()) {
                        String name = result.getString("name");
                        byte[] encryptedBytes = result.getBytes("encrypted_value");
                        String path = result.getString("path");
                        String domain = result.getString("host_key");
                        boolean secure = result.getBoolean("secure");
                        boolean httpOnly = result.getBoolean("httponly");
                        Date expires = result.getDate("expires_utc");

                        EncryptedCookie encryptedCookie = new EncryptedCookie(name,
                                                                              encryptedBytes, 
                                                                              expires,
                                                                              path, 
                                                                              domain, 
                                                                              secure,
                                                                              httpOnly, 
                                                                              cookieStore);

                        DecryptedCookie decryptedCookie = decrypt(encryptedCookie);

                        if(decryptedCookie != null){
                            cookies.add(decryptedCookie);
                        } else {
                            cookies.add(encryptedCook

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...