0

我想创建一个简单的 java 应用程序(用于 mac),它接收一个网站并在 Keychain 中输出与该网站相关联的密码。

我的问题是我的应用程序无法从输出中读取密码。如果我手动编写:

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

进入终端,我得到几行信息,然后 -> 密码:“mypassword”。但是在我的应用程序中,我只看到信息行,但应该是密码的最后一行不存在或为空。

我的代码:

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();
    }
}

我没有收到任何错误,只是上面的代码没有显示密码。如果这很重要,我正在使用 Eclipse。谢谢

应用程序打印:

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>

但最后一行丢失了,应该是

password: "mypassword"

已编辑

是不读取密码的InputStreamReader吗?有没有其他方法可以获取密码?

4

1 回答 1

0

您没有在输出中获得密码的原因是它没有打印到标准输出,而是打印到标准错误。

如果你在你的代码中替换child.getInputStream()child.getErrorStream()你会得到你正确的那条Password:secret!线。

您可以使用例如您的代码的以下修改版本:

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;
    }
}
于 2014-05-29T13:47:21.037 回答