【问题标题】:Adding certificate to keystore using java code使用 java 代码将证书添加到密钥库
【发布时间】:2012-04-22 02:12:29
【问题描述】:

我正在尝试使用服务器的 .cer 证书文件建立 https 连接。我可以使用浏览器手动获取证书文件,并使用 keytool 将其放入密钥库中。然后我可以使用 java 代码访问密钥库,获取我添加到密钥库的证书并连接到服务器。

然而,我现在甚至想实现使用 java 代码获取证书文件并将其添加到我的密钥库的过程,而不使用 keytool 或浏览器来获取证书。

谁能告诉我如何解决这个问题以及我需要做什么?

【问题讨论】:

  • 这有什么作用?我无法想象你为什么要这样做。
  • 我正在尝试在我的内部服务器中验证表单内容,然后再将客户端的请求发送回 hp 的服务器。我相信这可以防止任何基于浏览器的支付篡改,并且我的服务器可以进行所有预期的检查,而不是让 hp 的网站来做。但是,为了这样做,我需要使用 java 代码获取服务器的证书来执行握手。我不想每次都手动下载证书并将其放入我的密钥库中。我希望代码自动完成那部分..
  • 您的密钥库中不需要服务器证书。如果服务器配置正确,您所需要的只是服务器证书链的“根”。
  • 不幸的是,因为我连接到外部服务器,我无法控制它们的配置。
  • 您应该意识到这样做会丧失对服务器进行身份验证的能力。您不知道您是将付款信息发送给 HP 还是发送给诈骗者。任何合法的支付处理器都将正确配置其服务,以便您对其进行身份验证。否则,使用 TLS 完全没有意义。

标签: java https ssl-certificate keytool digital-certificate


【解决方案1】:

刚刚关注

https://docs.oracle.com/cd/E19509-01/820-3503/ggfgo/index.html https://www.sslshopper.com/article-most-common-java-keytool-keystore-commands.html

javac -cp .:/home/ec2-user/velu/*: QuickStart.java
java -cp .:/home/ec2-user/velu/*:  QuickStart


[ec2-user@ip-10-30-0-66 velu]$ ls
QuickStart.class  commons-codec-1.2.jar       input-payload.txt          logback-core-1.1.3.jar
QuickStart.java   commons-httpclient-3.1.jar  httpclient-4.5.jar  jdk-8u101-linux-x64.rpm    slf4j-api-1.7.12.jar
certificates      commons-logging-1.2.jar     httpcore-4.4.1.jar  logback-classic-1.1.3.jar



import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

public class QuickStart {

        public static void main(String[] args) throws Exception {
                System.setProperty("javax.net.ssl.keyStore", "/home/user/velu/certificates/myownOut.pkcs12");
                System.setProperty("javax.net.ssl.keyStorePassword", "password");

                System.setProperty("javax.net.ssl.trustStore", "/home/user/velu/certificates/myTrustStore");
                System.setProperty("javax.net.ssl.trustStorePassword", "password");

System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");
System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "debug");
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient", "debug");

                CloseableHttpClient httpclient = HttpClients.createDefault();

                HttpClientParams params = new HttpClientParams();
                params.setConnectionManagerClass(MultiThreadedHttpConnectionManager.class);
                HttpClient client = new HttpClient(params);

                HttpMethod m = new PostMethod("https://velu.org:443/Services/com/Echo");

                m.setRequestHeader("content-type", "application/xml");
                //m.setRequestHeader("Accept", "application/xml");
//              m.setRequestHeader("SOAPAction", "Echo");
                try {

                        ((PostMethod) m).setRequestEntity(new StringRequestEntity(getFileContent(), "application/xml", "UTF-8"));
                        System.out.println("VELU EXCUTING");
                        client.executeMethod(m);
                        if (m.getStatusCode() == 200) {
                                System.out.println("VELU RECEIVED:" + m.getResponseBodyAsString());
                        }
                } catch (IOException e) {
                        System.out.println(e.toString());
                } finally {
                        m.releaseConnection();
                }

        }

        public static String getFileContent() {

                BufferedReader br = null;
                String fileContent = "";
                try {

                        br = new BufferedReader(new FileReader(
                                        "/home/user/velu/input-payload.txt")); // Note that this file format should be proper.
                        String sCurrentLine = "";
                        while ((sCurrentLine = br.readLine()) != null) {
                                fileContent += sCurrentLine;
                        }
                        System.out.println(fileContent);

                } catch (IOException e) {
                        e.printStackTrace();
                } finally {
                        try {
                                if (br != null)
                                        br.close();
                        } catch (IOException ex) {
                                ex.printStackTrace();
                        }
                }
                return fileContent;
        }

【讨论】:

    【解决方案2】:

    我为此写了小库ssl-utils-android

    您可以通过提供资产目录中的文件名来简单地加载任何证书。

    用法:

    OkHttpClient client = new OkHttpClient();
    SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer");
    client.setSslSocketFactory(sslContext.getSocketFactory());
    

    【讨论】:

      【解决方案3】:

      编辑:This 似乎完全符合您的要求。

      使用以下代码可以在运行时添加信任库。

      import java.io.InputStream;
      import java.security.KeyStore;
      
      import javax.net.ssl.SSLContext;
      import javax.net.ssl.TrustManager;
      import javax.net.ssl.TrustManagerFactory;
      
      public class SSLClasspathTrustStoreLoader {
          public static void setTrustStore(String trustStore, String password) throws Exception {
              TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("X509");
              KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
              InputStream keystoreStream = SSLClasspathTrustStoreLoader.class.getResourceAsStream(trustStore);
              keystore.load(keystoreStream, password.toCharArray());
              trustManagerFactory.init(keystore);
              TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
              SSLContext sc = SSLContext.getInstance("SSL");
              sc.init(null, trustManagers, null);
              SSLContext.setDefault(sc);
          }
      }
      

      我使用此代码与活动目录服务器建立安全的 LDAP 连接。

      This也可以用,底部有一个类,可以在运行时导入证书。

      【讨论】:

      • 感谢您的回复桑德罗。我还有一个问题。我们如何获得特定网址的证书?
      • 谷歌搜索“从网站下载 Java 证书”我发现 this。它似乎完全符合您的要求。
      • 感谢 Sandro 的链接...它真的很有帮助。
      • @Sandro - 链接是 410 GONE
      猜你喜欢
      • 2016-08-03
      • 2018-01-24
      • 2013-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多