当前位置: 首页 > 面试题库 >

针对Java中的CA验证X.509证书

邓星光
2023-03-14
问题内容

可以说我有这样的东西(客户端代码):

TrustManager[] trustAllCerts = new TrustManager[]{
    new X509TrustManager() {

        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        @Override
        public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType) {
        }

        @Override
        public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType) {
        }
    }
};

SSLContext sslc = SSLContext.getInstance("TLS");
sslc.init(null, trustAllCerts, null);

SocketFactory sf = sslc.getSocketFactory();
SSLSocket s = (SSLSocket) sf.createSocket("127.0.0.1", 9124);

这段代码是完整的功能,但是我真的不知道如何根据pem文件中可用的一个具体的CA证书来验证服务器的证书。

所有证书均由我的自签名CA签名,这是我需要根据其进行验证的CA(仅针对此证书)。

每个答案表示赞赏。

编辑:

回应 jglouie (非常感谢您-无法投票支持您的答案)。

我创建了解决方案:

new X509TrustManager() {

        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        @Override
        public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType) {
        }

        @Override
        public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws CertificateException {
            InputStream inStream = null;
            try {
                // Loading the CA cert
                URL u = getClass().getResource("tcp/cacert.pem");
                inStream = new FileInputStream(u.getFile());
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                X509Certificate ca = (X509Certificate) cf.generateCertificate(inStream);
                inStream.close();

                for (X509Certificate cert : certs) {
                    // Verifing by public key
                    cert.verify(ca.getPublicKey());
                }
            } catch (Exception ex) {
                Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                try {
                    inStream.close();
                } catch (IOException ex) {
                    Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

        }
    }
};

问题答案:

我假设您的CA的自签名证书已按以下方式加载:

CertificateFactory cf = CertificateFactory.getInstance("X.509");   
FileInputStream finStream = new FileInputStream("CACertificate.pem"); 
X509Certificate caCertificate = (X509Certificate)cf.generateCertificate(finStream);

然后在检查证书的方法中:

@Override        
 public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)  throws CertificateException {

 if (certs == null || certs.length == 0) {  
      throw new IllegalArgumentException("null or zero-length certificate chain");  
 }

 if (authType == null || authType.length() == 0) {  
            throw new IllegalArgumentException("null or zero-length authentication type");  
  }

   //Check if certificate send is your CA's
    if(!certs[0].equals(caCertificate)){
         try
         {   //Not your CA's. Check if it has been signed by your CA
             certs[0].verify(caCertificate.getPublicKey())
         }
         catch(Exception e){   
              throw new CertificateException("Certificate not trusted",e);
         }
    }
    //If we end here certificate is trusted. Check if it has expired.  
     try{
          certs[0].checkValidity();
      }
      catch(Exception e){
            throw new CertificateException("Certificate not trusted. It has expired",e);
      }  
}

免责声明: 甚至没有尝试编译代码



 类似资料:
  • 我试图用Java来做这件事,但我认为这是一个一般的证书问题。我有根CA、根CA颁发的中间CA1、中间CA1颁发的中间CA2和中间CA2颁发的证书。 RootCA- 在不知道interCA2的情况下,是否可以通过interCA1验证证书?

  • 问题内容: 我正在慢慢地疯狂尝试配置Spring Security 3.0.0以保护应用程序。 我已将服务器(码头)配置为要求客户端身份验证(使用智能卡)。但是,我似乎无法正确获得applicationContext- security.xml和UserDetailsS​​ervice实现。 首先,从应用程序上下文文件中: UserDetailsS​​ervice看起来像这样: } 该应用程序具有

  • 我有一个servlet,它使用打包在.jar存档中的实用程序: 此实用工具获取xml文件流,针对xsd模式执行验证并解析它: xsd文件以: xml文件: Servlet Init方法抛出异常: 如何指定SAXParser在哪里需要xsd模式来验证xml文件? 附注。对不起,我的英语不好 UPD: 我正在尝试添加此属性: UPD2:在xml文件中使用“classpath:appcontext.xs

  • 我使用Spring Security使用x.509证书进行身份验证,它仅在浏览器密钥存储库中配置的客户端证书存在于服务器信任存储库中时才工作。 它目前是如何工作的: 我已将SSL客户端身份验证配置为可选(server.SSL.client auth=want,如本文所示) 我已经配置了一个包含所有客户端证书的服务器信任存储。如果客户端提供的证书位于信任存储中,则会创建相互SSL连接 当我的客户端证

  • 问题内容: 我需要使用给定的XSD文件验证XML文件。我只需要如果验证正常就返回true,否则返回false的方法。 问题答案: 仅返回true或false(也不需要任何外部库):

  • 问题内容: 但是,这将返回一条错误消息:线程“ main”中的异常java.lang.IllegalArgumentException:无法加载实现由http://www.w3.org/2001/XMLSchema -instance 指定的模式语言的SchemaFactory。 这是我的代码还是实际的xsd文件有问题? 问题答案: 该错误意味着您安装的Java没有任何可解析XMLSchema文件