私たちのシステムには、自己署名証明書を鍵ストアに自動的に生成するためのコードがいくつかあり、それがJettyによって使用されます。与えられたホストのためのキーがすでに存在する場合は何も起こりませんが、それが存在しない場合、我々はこのように、新しいキーを生成します。Jettyのキーストアに複数の証明書がある場合、どのように選択しますか?
public void generateKey(String commonName) {
X500Name x500Name = new X500Name("CN=" + commonName);
CertAndKeyGen keyPair = new CertAndKeyGen("DSA", "SHA1withDSA");
keyPair.generate(1024);
PrivateKey privateKey = keyPair.getPrivateKey();
X509Certificate certificate = keyPair.getSelfCertificate(x500Name, 20*365*24*60*60);
Certificate[] chain = { certificate };
keyStore.setEntry(commonName, privateKey, "secret".toCharArray(), chain);
}
唯一の鍵と証明書があるので、これはすべてが限り正常に動作しますキーストアであなたが複数のキーを持っていたら、あなたが接続しようとすると、奇妙なことが起こる:
java.io.IOException: HTTPS hostname wrong: should be <127.0.0.1>
これは非常に神秘エラーだったが、私は最終的にサーバに接続していることを主張するユニットテストを書くことで、それを追跡するために管理します証明書のCNがホスト名と一致しています。私が見つけたのはかなり面白かったです - 桟橋はクライアントに提示する証明書を任意に選択するようですが、一貫しています。例えば
は: "CN = localhost" をし、 "CN = cheese.mydomainは" キーストア内にある場合
- は、それは常に "CN = cheese.mydomain" を選びました。
- "CN = 127.0.0.1"と "CN = cheese.mydomain"がキーストアにある場合、常に "CN = cheese.mydomain"を選択しました。
- "CN = 192.168.222.100"(cheese.mydomain)と "CN = cheese.mydomain"がキーストアにある場合、常に "CN = 192.168.222.100"を選択しました。
私は、店舗の証明書を印刷して、それを印刷するコードを書いて、一貫して最初の証明書またはそのようなものを一貫して選択していないことがわかりました。
どのような基準を使用するのですか?最初はlocalhostは特別だと思っていましたが、3番目の例は私を完全に困惑させました。
これは、私の場合、SunX509であるKeyManagerFactoryによって何らかの形で決定されます。
ええ、私たちはIPアドレスも持っていることを発見しました。その結果、独自のHostnameVerifierを書いて一致するかどうかをチェックし、真を返します。もともとは、常に真を返すHostnameVerifierを持っていましたが、それは明白な理由のために投げ出されなければなりませんでした。既存のユーザーの多くは、IPアドレスを「ホスト名」として構成しており、積極的に攻撃したくはありません。 – Trejkaz