13

クライアント認証でTomcat httpコネクタを使用しています。クライアントがサーバーへの新しい接続を開始して証明書を送信した場合、証明書を取得して、Java コードで受信証明書から共通名を読み取ることができますか? はいの場合、どのように?

ありがとうアディ

4

2 に答える 2

23

javax.servlet.request.X509Certificateの属性を取得することで、クライアント証明書チェーンを取得できますHttpServletRequestX509Certificateこれはの配列で、最初のもの (位置 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();

次に、この回答で説明されているように、このプリンシパル (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());
}

(BouncyCastle を使用X509Nameして各 RDN を取得することもできます。)

X.509 証明書では、サブジェクト DN は RDN の順序付けられたシーケンスであり、それぞれが AVA (属性値アサーション) のセットです (例:CN=...O=.... 原則として、RDN ごとに複数の AVA が存在する可能性があるため、ここで問題が発生しますが、これは非常にまれです。RDN ごとに 1 つの AVA しかないとほぼ想定できます。(おそらく、この答えは興味深いかもしれません。)

于 2012-08-14T11:37:46.460 に答える
1

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());
                }
            }
        }
于 2012-08-14T06:53:15.030 に答える