我正在测试以下代码以在我的机器上查找证书哈希代码,然后使用 Java 7 在不同的虚拟机上运行相同的代码。
我很困惑地看到哈希码上的差异。
这是我的代码:
import javax.net.ssl.HttpsURLConnection;
import java.net.URL;
import java.security.cert.Certificate;
public class Main {
public static void main(String[] args) throws Exception {
HttpsURLConnection urlc = (HttpsURLConnection) new URL("https://www.google.com").openConnection();
print_https_cert(urlc);
}
private static void print_https_cert(HttpsURLConnection con) {
if (con != null) {
try {
System.out.println("Response Code : " + con.getResponseCode());
System.out.println("Cipher Suite : " + con.getCipherSuite());
System.out.println("\n");
Certificate[] certs = con.getServerCertificates();
for (Certificate cert : certs) {
System.out.println("Cert Type : " + cert.getType());
System.out.println("Cert Hash Code : " + cert.hashCode());
System.out.println("Cert Public Key Algorithm : "
+ cert.getPublicKey().getAlgorithm());
System.out.println("Cert Public Key Format : "
+ cert.getPublicKey().getFormat());
System.out.println("\n");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
这是我使用 java 1.7.0_79 得到的结果
Response Code : 200
Cipher Suite : TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Cert Type : X.509 Cert Hash Code : 10920939 Cert Public Key Algorithm : RSA Cert Public Key Format : X.509
Cert Type : X.509 Cert Hash Code : 6561088 Cert Public Key Algorithm : RSA Cert Public Key Format : X.509
Cert Type : X.509 Cert Hash Code : 8774863 Cert Public Key Algorithm : RSA Cert Public Key Format : X.509
这里是 java 1.8.0_77 的输出
Response Code : 200 Cipher Suite : TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Cert Type : X.509 Cert Hash Code : -106561125 Cert Public Key Algorithm : RSA Cert Public Key Format : X.509
Cert Type : X.509 Cert Hash Code : 771393018 Cert Public Key Algorithm : RSA Cert Public Key Format : X.509
Cert Type : X.509 Cert Hash Code : 349192256 Cert Public Key Algorithm : RSA Cert Public Key Format : X.509
散列码应该相同还是我在这里遗漏了什么?
最佳答案
java.security.cert.Certificate
的 hascode() 方法已更改。至少对于 openjdk:
hashcode 允许在 jdk 版本之间改变。它的主要用途是将 Object
存储在 HashMap
中。将对象的哈希码“外部”传递或持久化是绝对不可忽视的。
如果您需要证书的哈希和,我建议您实现自己的哈希函数,这样您就不会依赖于允许更改的内部行为。
没有严格的算法来计算 Java 对象的哈希码。实现者只需要与 hashcode() 和 equals() 契约保持一致。
http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--
关于java - 服务器证书哈希码在 Java 版本之间发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37735902/