Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java load(InputStream,char[]密码);如何知道客户端的密码?_Java_Ssl_Certificate - Fatal编程技术网

Java load(InputStream,char[]密码);如何知道客户端的密码?

Java load(InputStream,char[]密码);如何知道客户端的密码?,java,ssl,certificate,Java,Ssl,Certificate,我知道要加载要使用的证书,我需要调用KeyStore.load(InputStream,char[])。如果需要密码,如何在客户端加载证书?连接到Google时我不需要这个,但我想使用信任管理器来验证Google证书。我也无法创建SSLServerSocket并在不加载证书的情况下连接到它。 编辑:添加代码: package testing; import java.io.BufferedReader; import java.io.FileInputStream; import java.

我知道要加载要使用的证书,我需要调用
KeyStore.load(InputStream,char[])。如果需要密码,如何在客户端加载证书?连接到Google时我不需要这个,但我想使用信任管理器来验证Google证书。我也无法创建
SSLServerSocket
并在不加载证书的情况下连接到它。
编辑:添加代码:

package testing;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class SSLClientTest {
    public static void main(String[] args) {
        int port = 443;
        String host = "google.com";

        try {

            SSLContext sc = SSLContext.getInstance("TLSv1.2");
            KeyStore ks = KeyStore.getInstance("JKS");
            InputStream ksIs = new FileInputStream("securecert.certificate");
            try {
                ks.load(ksIs, "pwdpwdpwd".toCharArray());
            } finally {
                if (ksIs != null) {
                    ksIs.close();
                }
            }
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(ks, "pwdpwdpwd".toCharArray());
            sc.init(kmf.getKeyManagers(),
                    new TrustManager[] { new MyTrustManager() }, null);

            SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory
                    .getDefault();
            SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
            socket.startHandshake();
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            System.out.println(in.readLine());
            in.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static final class MyTrustManager implements X509TrustManager {

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[] {};
        }
    }
}

注意,我必须加载证书securecert.certificate,类似于代码ks.load(InputStream,char[]);我当然知道密码,但如果我不知道呢?那么如何使用信任管理器验证证书?这段代码只是锁定。请回答。谢谢

似乎您需要通过
SSL
进行客户端身份验证,并希望让用户输入其
密钥库的密码。根据您的解释,我假设每个已安装的客户端都有自己的本地路径的
密钥库
(如果不是,那么这个问题毫无意义,因为如果
密钥库
总是相同的,那么您不必每次都传递不同的密码……但是如果是这种情况,您必须检查此客户端是否安全)

因此,要让用户输入密码,您可以以不同的方式实例化
keystore
,而不是使用
keystore.getInstance(InputStream,Char[])
,您可以使用
keystore.Builder.newInstance
keystore.CallbackHandlerProtection
方法,您必须创建一个实现
javax.security.auth.callback.CallbackHandler
的类,该类必须重写
handle()
方法,例如使用swing或awt面板让用户引入密码。下面我向您展示一些示例代码,以指导您完成以下步骤:

加载密钥库 如果您需要更多信息,请访问,并查阅文档


希望这有帮助,

在客户端加载证书?你到底在干什么?您有一个java客户端,并且希望使用证书身份验证连接到Web服务器。。。或者,您只想验证
https
连接,根据您的
信任库验证服务器证书?。也许有更多的信息我们可以帮助你。@albciff你来了!在客户端不需要证书或密钥管理器,除非服务器要求您发送客户端证书,也就是说,除非您正在进行相互身份验证。如果您有客户机证书,它将作为客户机用户生成的私钥对开始使用,进入客户机用户创建的密钥库,因此客户机用户知道他使用的密码。因此,当您需要它时,请询问用户。或者让他们都同意一个密码,并将其硬编码到您的应用程序中,如果您认为这是安全的,并且他们都同意的话。我不会。我很感激这个答案,它澄清了我的疑问:“这里的‘提示’是什么意思,它是否会自动提示输入密码的对话框等等?”(显然,它不会,留给我们来实现Swing/AWT部分。)@FaithrePaper感谢您的反馈,我离开这一部分是因为它非常具体,取决于实现。。。
提示
这不是强制性的,例如,可能有人从属性文件中读取密码。
import java.io.File;
import java.security.KeyStore;
import java.security.Provider;
import java.util.Enumeration;

public class KeyStoreCallbackSample {

    public static void main(String args[]) throws Exception {
        // instantiate a keystore to get the provider for specific type
        KeyStore ks = KeyStore.getInstance("JKS");

        // create the callback handler to get the password
        KeyStore.CallbackHandlerProtection cbhp = new KeyStore.CallbackHandlerProtection(new YourImplementationCallbackHander());
        // create the builder passing keystoreType, provider, keystore file, and callbackhandler
        KeyStore.Builder builder = KeyStore.Builder.newInstance("JKS", ks.getProvider(), new File("/path/YourKeyStore.jks"), cbhp);
        // create the keystore
        ks = builder.getKeyStore();

        // print the keystores alias to check if all it's load correctly
        Enumeration<String> aliases = ks.aliases();
        while(aliases.hasMoreElements()){
            System.out.println(aliases.nextElement());
        }       
    }
}   
import java.io.IOException;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

/**
 * PIN handler for keystores
 */
public class PinInputHandler implements CallbackHandler {

    private char[] lastPassword;

    public PinInputHandler(){}

    // implement this method to handle the callback
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (Callback cb : callbacks) {
            if (cb instanceof javax.security.auth.callback.PasswordCallback) {
                javax.security.auth.callback.PasswordCallback pcb = (javax.security.auth.callback.PasswordCallback) cb;
                try {
                    this.lastPassword = // HERE YOUR SWING OR AWT OR ANOTHER WAY TO GET THE PASSWORD FROM THE CLIENT
                } catch (Exception e) {}
                pcb.setPassword(this.lastPassword);
            }
        }
    }
}