How to view internet-passwords from Keychain using Java (mac)

0

I would like to create a simple java app (for mac) that takes in a website and outputs my password associated with the website in Keychain.

My problem is that my app can't read the password from the output. If I manually write:

security find-internet-password -gs www.google.com

into the Terminal I get a few lines of info and then -> password: "mypassword". But in my application I only see the lines of info but the last line which should be the password is not there or null.

My code:

public static void command(){
    try{

        String command = "security find-internet-password -gs www.google.com";
        Process child = Runtime.getRuntime().exec(command);

        BufferedReader r = new BufferedReader(new InputStreamReader(child.getInputStream()));
        String s;

        while ((s = r.readLine()) != null) {
            System.out.println(s);
        }
        System.out.println(r.readLine());
        r.close();
    }
    catch (IOException e) {
        e.printStackTrace();
    }
}

I'm not getting any errors but simply the code above is not showing the password. I'm using Eclipse if that matters. Thanks

The application prints:

keychain: "/Users/*username*/Library/Keychains/login.keychain"
class: "inet"
attributes:
    0x00000007 <blob>="www.google.com"
    0x00000008 <blob>=<NULL>
    "acct"<blob>="*username*"
    "atyp"<blob>="http"
    "cdat"<timedate>=0x323031*numbers*3333325A00  "2011*numbers*132Z\000"
    "crtr"<uint32>="rimZ"
    "cusi"<sint32>=<NULL>
    "desc"<blob>=<NULL>
    "icmt"<blob>=<NULL>
    "invi"<sint32>=<NULL>
    "mdat"<timedate>=0x3230331*numbers*33834375A00  "20115*numbers*3847Z\000"
    "nega"<sint32>=<NULL>
    "path"<blob>="/"
    "port"<uint32>=0x00000000 
    "prot"<blob>=<NULL>
    "ptcl"<uint32>="htps"
    "scrp"<sint32>=<NULL>
    "sdmn"<blob>="www.google.com"
    "srvr"<blob>="www.google.com"
    "type"<uint32>=<NULL>

but the last line is missing and should be

password: "mypassword"

Edited

Is it the InputStreamReader that does not read the password? Is there another way to get the password?

java
terminal
passwords
keychain
inputstreamreader
asked on Stack Overflow Mar 21, 2014 by PaprikaSauce • edited Apr 2, 2014 by PaprikaSauce

1 Answer

0

The reason why you do not get the password in the output is that it is not printed to the stdout but to the stderr instead.

If you replace child.getInputStream() with child.getErrorStream() in your code will get you righ that Password:secret! line.

You could use e.g. the following modified version of your code:

public static boolean command(String host) {
    try {

        String command = "security find-internet-password -gs " + host;
        Process child = Runtime.getRuntime().exec(command);

        try (BufferedReader out = new BufferedReader(new InputStreamReader(
                child.getInputStream()));
                BufferedReader err = new BufferedReader(
                        new InputStreamReader(child.getErrorStream()))) {
            String user = null;
            String password = null;
            String s;

            while ((s = out.readLine()) != null) {
                if (s.matches(" *\"acct\".*")) {
                    user = s.replaceAll("^.*=\"", "").replace("\"", "");
                }
            }
            s = err.readLine();
            password = s.replaceAll("^.*: *\"", "").replace("\"", "");
            System.out.println("user: " + user);
            System.out.println("pwd: " + password);
            return true;
        }
    } catch (IOException e) {
        return false;
    }
}
answered on Stack Overflow May 29, 2014 by Marco Torchiano

User contributions licensed under CC BY-SA 3.0