java 在Tomcat中读出传入的证书

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11945013/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 07:02:03  来源:igfitidea点击:

Read out incoming certificate in Tomcat

javatomcatsslcertificatessl-client-authentication

提问by adihubba

i use a tomcat http connector with client-authentification. If a client start a new connection to my server and sends his certificate, can i get the certificate and read the common name from the incoming certificate out in my java code. If yes, how?

我使用带有客户端身份验证的 tomcat http 连接器。如果客户端开始与我的服务器的新连接并发送他的证书,我可以获取证书并在我的 java 代码中从传入的证书中读取通用名称。如果是,如何?

thanks adi

谢谢阿迪

回答by Bruno

You can get the client certificate chain by getting the javax.servlet.request.X509Certificateattribute on your HttpServletRequest. This is an array of X509Certificateswhere the first one (position 0) is the actual client certificate (the rest of the chain may be present if intermediate CA certificates are required).

您可以通过获取获取客户端证书链javax.servlet.request.X509Certificate的属性在你的HttpServletRequest。这是一个X509Certificates数组,其中第一个(位置 0)是实际的客户端证书(如果需要中间 CA 证书,则链的其余部分可能存在)。

X509Certificate certs[] = 
    (X509Certificate[])req.getAttribute("javax.servlet.request.X509Certificate");
// ... Test if non-null, non-empty.

X509Certificate clientCert = certs[0];

// Get the Subject DN's X500Principal
X500Principal subjectDN = clientCert.getSubjectX500Principal();

You can then get the various RDNs (relative distinguished name) in this principal (e.g. CN) as described in this answer:

然后,您可以获得此主体(例如 CN)中的各种 RDN(相对专有名称),如本答案所述

import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;

String dn = subjectDN.getName();
LdapName ldapDN = new LdapName(dn);
for(Rdn rdn: ldapDN.getRdns()) {
    System.out.println(rdn.getType() + " -> " + rdn.getValue());
}

(You could also use BouncyCastle's X509Nameto get each RDN.)

(您也可以使用 BouncyCastle'sX509Name来获取每个 RDN。)

In an X.509 certificate, the Subject DN is an ordered sequence of RDNs, each of which is a set of AVAs (Attribute Value Assertions), for example CN=...or O=.... In principle, there can be multiple AVAs per RDN, which would cause problems here, but this is very rare. You can almost assume that there is only one AVA per RDN. (Perhaps this answermight be of interest.)

在 X.509 证书中,主题 DN 是 RDN 的有序序列,每个 RDN 是一组 AVA(属性值断言),例如CN=...O=...。原则上,每个 RDN 可以有多个 AVA,这会导致问题,但这种情况非常罕见。您几乎可以假设每个 RDN 只有一个 AVA。(也许这个答案可能会引起人们的兴趣。)

回答by adihubba

Credit to mazaneicha:

归功于 Mazaneicha:

        String cipherSuite = (String) req.getAttribute("javax.servlet.request.cipher_suite");

        if (cipherSuite != null) {
            X509Certificate certChain[] = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate");
            if (certChain != null) {
                for (int i = 0; i < certChaNin.length; i++) {
                    System.out.println ("Client Certificate [" + i + "] = "
                            + certChain[i].toString());
                }
            }
        }