有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何访问chromium(或任何其他浏览器)cookie

我有一个向谷歌发送请求的java应用程序。com并解析谷歌在查询后返回的搜索结果。在谷歌没有开始为所有未经授权的用户安装capcha之前,它运行良好。现在我遇到了麻烦,因为要访问搜索结果,用户需要确认capcha。以下是我对如何解决这个问题的想法:

  1. 将JxBrowser添加到我的应用程序中,但这太贵了(成本超过1千澳元,而且对我来说实施起来很复杂)

  2. 为谷歌硬编码我自己的cookies。但是我的acc会有很多人的请求,我百分之百确定在这种情况下,谷歌会给每个人提供capcha

  3. 最后一个选项(最现实的)是让用户访问谷歌并完成capcha,然后以某种方式访问浏览器cookie

我该怎么做才能让我的应用程序再次工作?有人有这样的问题吗

谢谢你的帮助。谢谢


共 (1) 个答案

  1. # 1 楼答案

    经过一天的谷歌搜索和几次尝试,我终于得到了可以访问Chromium和Mozilla cookies的代码。这就是:

    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.ResultSetMetaData;
    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 Main {
    
        public static void main(String[] args) throws IOException {
            ChromeBrowser chrome = new ChromeBrowser();
            //MozillaBrowser mozilla = new MozillaBrowser();
            args=new String[]{"google.com"};
            if(args!=null&&args.length>0) {
                Set<Cookie> cookies = chrome.getCookiesForDomain(args[0]);
                //Set<Cookie> cookies = mozilla.getCookiesForDomain(args[0]);
                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 Cookie(String name, String dencryptedValue, Date expires, String path, String domain, boolean secure, boolean httpOnly, File cookieStore) {
                this.name = name;
                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 DecryptedCookie(String name, String decryptedValue, Date expires, String path, String domain, boolean secure, boolean httpOnly, File cookieStore) {
                super(name, decryptedValue, 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);
    
        }
    
        public static class MozillaBrowser extends Browser {
    
            protected DecryptedCookie decrypt(EncryptedCookie encryptedCookie){return null;}
    
            /**
             * Returns a set of cookie store locations
             * @return
             */
            @Override
            protected Set<File> getCookieStores() {
                HashSet<File> cookieStores = new HashSet<File>();
    
                for(String path:new String[]{"\\Application Data\\Mozilla\\Firefox\\Profiles\\","\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\","/Library/Application Support/Firefox/Profiles/","/.config/Firefox/","/.config/firefox/","/.mozilla/firefox/"}){
                    if(new File(System.getProperty("user.home")+path).exists())for(File file:new File(System.getProperty("user.home")+path).listFiles()){
                        if(file.isDirectory()&&file.getName().matches("(?iu)^.*?\\.default$"))cookieStores.add(new File(System.getProperty("user.home")+path+file.getName()+File.separator+"cookies.sqlite"));
                    }
                }
    
                return cookieStores;
            }
    
            public 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());
                        Class.forName("org.sqlite.JDBC");
                        connection=DriverManager.getConnection("jdbc:sqlite:"+cookieStoreCopy.getAbsolutePath());
                        Statement statement=connection.createStatement();
                        statement.setQueryTimeout(30);
                        ResultSet result=null;
                        if(domainFilter==null||domainFilter.isEmpty())result=statement.executeQuery("select * from cookies");
                        else result = statement.executeQuery("select * from moz_cookies where HOST like \"%"+domainFilter+"%\"");//ID,BASEDOMAIN,APPID,INBROWSERELEMENT,NAME,VALUE,HOST,PATH,EXPIRY,LASTACCESSED,CREATIONTIME,ISSECURE
                        while(result.next()){
                            String name=result.getString("NAME");
                            String value=result.getString("VALUE");
                            String path=result.getString("PATH");
                            String domain=result.getString("HOST");
                            boolean secure=ChromeBrowser.hasColumn(result,"ISSECURE")?result.getBoolean("ISSECURE"):false;
                            Date expires=result.getDate("EXPIRY");
    
                            DecryptedCookie decryptedCookie=new DecryptedCookie(name,value,expires,path,domain,secure,false,cookieStore);
    
                            cookies.add(decryptedCookie);
                            cookieStoreCopy.delete();
                        }
                    }
                    catch(Exception e){e.printStackTrace();}
                    finally{
                        try{
                            if(connection!=null)connection.close();
                        }
                        catch(SQLException e){}
                    }
                }
                return cookies;
    
            }
        }
    
        /**
         * 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\\Yandex\\YandexBrowser\\User Data\\Default\\Cookies"));
                cookieStores.add(new File(System.getProperty("user.home") + "\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Cookies"));
                //cookieStores.add(new File(System.getProperty("user.home") + "\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\nmx4n1pd.default\\cookies.sqlite"));
    
                // 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;
            }
    
            public static boolean hasColumn(ResultSet rs, String columnName) throws SQLException {
                ResultSetMetaData rsmd = rs.getMetaData();
                int columns = rsmd.getColumnCount();
                for (int x = 1; x <= columns; x++) {
                    if (columnName.equals(rsmd.getColumnName(x))) {
                        return true;
                    }
                }
                return false;
            }
    
            /**
             * 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 = ChromeBrowser.hasColumn(result,"secure")?result.getBoolean("secure"):false;
                            boolean httpOnly = ChromeBrowser.hasColumn(result,"httponly")?result.getBoolean("httponly"):false;
                            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(encryptedCookie);
                            }
                            cookieStoreCopy.delete();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        // if the error message is "out of memory",
                        // it probably means no database file is found
                    } finally {
                        try {
                            if (connection != null){
                                connection.close();
                            }
                        } catch (SQLException e) {
                            // connection close failed
                        }
                    }
                }
                return cookies;
            }
    
            /**
             * Decrypts an encrypted cookie
             * @param encryptedCookie
             * @return
             */
            @Override
            protected DecryptedCookie decrypt(EncryptedCookie encryptedCookie) {
                byte[] decryptedBytes = null;
                if(OS.isWindows()){
                    try {
                        System.setProperty("jna.predictable_field_order","true");
                        decryptedBytes = Crypt32Util.cryptUnprotectData(encryptedCookie.getEncryptedValue());
                    } catch (Exception e){
                        decryptedBytes = null;
                    }
                } else if(OS.isLinux()){
                    try {
                        byte[] salt = "saltysalt".getBytes();
                        char[] password = "peanuts".toCharArray();
                        char[] iv = new char[16];
                        Arrays.fill(iv, ' ');
                        int keyLength = 16;
    
                        int iterations = 1;
    
                        PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, keyLength * 8);
                        SecretKeyFactory pbkdf2 = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    
                        byte[] aesKey = pbkdf2.generateSecret(spec).getEncoded();
    
                        SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
    
                        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                        cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(new String(iv).getBytes()));
    
                        // if cookies are encrypted "v10" is a the prefix (has to be removed before decryption)
                        byte[] encryptedBytes = encryptedCookie.getEncryptedValue();
                        if (new String(encryptedCookie.getEncryptedValue()).startsWith("v10")) {
                            encryptedBytes = Arrays.copyOfRange(encryptedBytes, 3, encryptedBytes.length);
                        }
                        decryptedBytes = cipher.doFinal(encryptedBytes);
                    } catch (Exception e) {
                        decryptedBytes = null;
                    }
                } else if(OS.isMac()){
                    // access the decryption password from the keyring manager
                    if(chromeKeyringPassword == null){
                        try {
                            chromeKeyringPassword = getMacKeyringPassword("Chrome Safe Storage");
                        } catch (IOException e) {
                            decryptedBytes = null;
                        }
                    }
                    try {
                        byte[] salt = "saltysalt".getBytes();
                        char[] password = chromeKeyringPassword.toCharArray();
                        char[] iv = new char[16];
                        Arrays.fill(iv, ' ');
                        int keyLength = 16;
    
                        int iterations = 1003;
    
                        PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, keyLength * 8);
                        SecretKeyFactory pbkdf2 = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    
                        byte[] aesKey = pbkdf2.generateSecret(spec).getEncoded();
    
                        SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
    
                        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                        cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(new String(iv).getBytes()));
    
                        // if cookies are encrypted "v10" is a the prefix (has to be removed before decryption)
                        byte[] encryptedBytes = encryptedCookie.getEncryptedValue();
                        if (new String(encryptedCookie.getEncryptedValue()).startsWith("v10")) {
                            encryptedBytes = Arrays.copyOfRange(encryptedBytes, 3, encryptedBytes.length);
                        }
                        decryptedBytes = cipher.doFinal(encryptedBytes);
                    } catch (Exception e) {
                        decryptedBytes = null;
                    }
                }
    
                if(decryptedBytes == null){
                    return null;
                } else {        
                    return new DecryptedCookie(encryptedCookie.getName(),
                                               encryptedCookie.getEncryptedValue(),
                                               new String(decryptedBytes),
                                               encryptedCookie.getExpires(),
                                               encryptedCookie.getPath(),
                                               encryptedCookie.getDomain(),
                                               encryptedCookie.isSecure(),
                                               encryptedCookie.isHttpOnly(),
                                               encryptedCookie.getCookieStore());
                }
            }
    
            /**
             * Accesses the apple keyring to retrieve the Chrome decryption password
             * @param application
             * @return
             * @throws IOException
             */
            private static String getMacKeyringPassword(String application) throws IOException {
                Runtime rt = Runtime.getRuntime();
                String[] commands = {"security", "find-generic-password","-w", "-s", application};
                Process proc = rt.exec(commands);
                BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
                String result = "";
                String s = null;
                while ((s = stdInput.readLine()) != null) {
                    result += s;
                }
                return result;
            }
    
        }
    
    }