2009-08-13 41 views
30

Tôi có một ứng dụng khách java đang gọi một hoạt động dịch vụ web có chứng chỉ "vân tay" làm thông số. Tôi tin rằng dấu vân tay là một loại băm SHA1, trong định dạng chuỗi thập lục phân, của khóa công khai của cert, nhưng tôi không chắc chắn.Cách lấy/tính toán dấu vân tay của chứng chỉ X509 trong Java?

Khuôn khổ .NET dường như bao gồm một cách đơn giản để nhận giá trị này (thuộc tính X509Certificate2.Thumbprint). Xem thuộc tính file cer trong Windows cũng sẽ hiển thị vân tay, trông giống như: do đó

a6 9c fd b0 58 0d a4 ee ae 9a 47 75 24 c3 0b 9f 5d b6 1c 77 

Câu hỏi của tôi là: Có ai biết làm thế nào để truy xuất hoặc tính toán chuỗi vân tay này trong Java, nếu tôi có một thể hiện của một java.security.cert.X509Certificate?

+0

bản demo Java này (URLConnection) oogle của kết nối đến một url https và in/tính toán tất cả các loại dấu vân tay, bao gồm cả pin-sha256, SKI và Thumbprints: https://github.com/ecki/JavaCryptoTest/ blob/master/src/main/java/net/eckenfels/test/ssl/UrlInspect.java – eckes

Trả lời

64

Hàm băm SHA-1 của số DER encoding của chứng chỉ là những gì .NET đang nhận được với X509Certificate2.Thumbprint.

Như đã nói ở trên remarks on MSDN:

Các vân tay được tự động tạo ra bằng cách sử dụng thuật toán SHA1 và không thể chất tồn tại trong các chứng chỉ. Vì dấu vân tay là một giá trị duy nhất cho chứng chỉ, nó thường được sử dụng để tìm một chứng chỉ cụ thể trong kho chứng chỉ.

thư viện chuẩn của Java không cung cấp các vân tay trực tiếp, nhưng bạn có thể nhận được nó như thế này:

DatatypeConverter.printHexBinary(
     MessageDigest.getInstance("SHA-1").digest(
       cert.getEncoded())).toLowerCase(); 

Dưới đây là một ví dụ cách đầy đủ sử dụng một tập tin PEM thuận tiện truy cập:

  1. Tạo stackoverflow.crt.pem:

    -----BEGIN CERTIFICATE----- 
    MIIHHjCCBgagAwIBAgIQDhG71w1UtxDQxvVAtrUspDANBgkqhkiG9w0BAQsFADBw 
    MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 
    d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz 
    dXJhbmNlIFNlcnZlciBDQTAeFw0xNjA1MjEwMDAwMDBaFw0xOTA4MTQxMjAwMDBa 
    MGoxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJOWTERMA8GA1UEBxMITmV3IFlvcmsx 
    HTAbBgNVBAoTFFN0YWNrIEV4Y2hhbmdlLCBJbmMuMRwwGgYDVQQDDBMqLnN0YWNr 
    ZXhjaGFuZ2UuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr0YD 
    zscT5i6T2FaRsTGNCiLB8OtPXu8N9iAyuaROh/nS0kRRsN8wUMk1TmgZhPuYM6oF 
    S377V8W2LqhLBMrPXi7lnhvKt2DFWCyw38RrDbEsM5dzVGErmhux3F0QqcTI92zj 
    VW61DmE7NSQLiR4yonVpTpdAaO4jSPJxn8d+4p1sIlU2JGSk8LZSWFqaROc7KtXt 
    lWP4HahNRZtdwvL5dIEGGNWx+7B+XVAfY1ygc/UisldkA+a3D2+3WAtXgFZRZZ/1 
    CWFjKWJNMAI6ZBAtlbgSNgRYxdcdleIhPLCzkzWysfltfiBmsmgz6VCoFR4KgJo8 
    Gd3MeTWojBthM10SLwIDAQABo4IDuDCCA7QwHwYDVR0jBBgwFoAUUWj/kK8CB3U8 
    zNllZGKiErhZcjswHQYDVR0OBBYEFFrBQmPCYhOznZSEqjIeF8tto4Z7MIIB6AYD 
    VR0RBIIB3zCCAduCEyouc3RhY2tleGNoYW5nZS5jb22CEXN0YWNrb3ZlcmZsb3cu 
    Y29tghMqLnN0YWNrb3ZlcmZsb3cuY29tgg1zdGFja2F1dGguY29tggtzc3RhdGlj 
    Lm5ldIINKi5zc3RhdGljLm5ldIIPc2VydmVyZmF1bHQuY29tghEqLnNlcnZlcmZh 
    dWx0LmNvbYINc3VwZXJ1c2VyLmNvbYIPKi5zdXBlcnVzZXIuY29tgg1zdGFja2Fw 
    cHMuY29tghRvcGVuaWQuc3RhY2thdXRoLmNvbYIRc3RhY2tleGNoYW5nZS5jb22C 
    GCoubWV0YS5zdGFja2V4Y2hhbmdlLmNvbYIWbWV0YS5zdGFja2V4Y2hhbmdlLmNv 
    bYIQbWF0aG92ZXJmbG93Lm5ldIISKi5tYXRob3ZlcmZsb3cubmV0gg1hc2t1YnVu 
    dHUuY29tgg8qLmFza3VidW50dS5jb22CEXN0YWNrc25pcHBldHMubmV0ghIqLmJs 
    b2dvdmVyZmxvdy5jb22CEGJsb2dvdmVyZmxvdy5jb22CGCoubWV0YS5zdGFja292 
    ZXJmbG93LmNvbYIVKi5zdGFja292ZXJmbG93LmVtYWlsghNzdGFja292ZXJmbG93 
    LmVtYWlsMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB 
    BQUHAwIwdQYDVR0fBG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29t 
    L3NoYTItaGEtc2VydmVyLWc1LmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNl 
    cnQuY29tL3NoYTItaGEtc2VydmVyLWc1LmNybDBMBgNVHSAERTBDMDcGCWCGSAGG 
    /WwBATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BT 
    MAgGBmeBDAECAjCBgwYIKwYBBQUHAQEEdzB1MCQGCCsGAQUFBzABhhhodHRwOi8v 
    b2NzcC5kaWdpY2VydC5jb20wTQYIKwYBBQUHMAKGQWh0dHA6Ly9jYWNlcnRzLmRp 
    Z2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJIaWdoQXNzdXJhbmNlU2VydmVyQ0EuY3J0 
    MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAAzJAMGSdKoX1frdqNlN 
    iXu8Gcbsm/DxWMXpcTXlZn8s+/qQQoc+/3o0CK3C8/j9n5DmsYa88P6Ntt5ysDs+ 
    b0ynXFva4CAEyKaoPM4SIpOjwfWBRSUOqAIkQO2/LhKBwT/EnpaIHIKGnI0UdXLQ 
    oDfkMDg6mgJsEBsKdKF5EfEX7iU3NO5xVJPJE8/R0btLAdYwxB9S6fSpCXGe2HqQ 
    D101O/7/4MWNdFSbfdDSFcn5oEm+idimrqiNrF5knmuJy4qPBkL7thNuGK6rvYCF 
    ZJM03ZEZhkQmn2jG/7LgjfwZmvfcITeADCpylf88bL+lf+vxe6cCl9CyqWgBDpsI 
    xpE= 
    -----END CERTIFICATE----- 
    
  2. Tạo X509.java:

    import javax.xml.bind.DatatypeConverter; 
    import java.io.FileInputStream; 
    import java.io.FileNotFoundException; 
    import java.security.MessageDigest; 
    import java.security.NoSuchAlgorithmException; 
    import java.security.cert.CertificateEncodingException; 
    import java.security.cert.CertificateException; 
    import java.security.cert.CertificateFactory; 
    import java.security.cert.X509Certificate; 
    
    public final class X509 { 
        public static void main(String[] args) 
          throws FileNotFoundException, CertificateException, NoSuchAlgorithmException { 
         FileInputStream is = new FileInputStream(args[0]); 
         CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); 
         X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(is); 
         String thumbprint = getThumbprint(cert); 
         System.out.println(thumbprint); 
        } 
    
        private static String getThumbprint(X509Certificate cert) 
          throws NoSuchAlgorithmException, CertificateEncodingException { 
         MessageDigest md = MessageDigest.getInstance("SHA-1"); 
         byte[] der = cert.getEncoded(); 
         md.update(der); 
         byte[] digest = md.digest(); 
         String digestHex = DatatypeConverter.printHexBinary(digest); 
         return digestHex.toLowerCase(); 
        } 
    } 
    
  3. Biên dịch chương trình với Java 8:

    javac X509.java 
    

    Hoặc Java 9 - do mô-đun JDK/JPMS - DataTypeConverter không có trong java.base, nhưng java.xml.bind, vì vậy bạn cần phải phụ thuộc rõ ràng vào nó trong quá trình xây dựng của bạn :

    javac --add-modules java.xml.bind X509.java 
    

    Nếu không, trên Java 9, bạn có được điều này khi bạn cố gắng để xây dựng nó:

    X509.java:3: error: package javax.xml.bind is not visible 
         import javax.xml.bind.DatatypeConverter; 
         ^
         (package javax.xml.bind is declared in module java.xml.bind, which is not in the module graph) 
         1 error 
    
  4. Run nó với Java 8:

    java X509 stackoverflow.crt.pem 
    

    Trong Java 9 - do với mô-đun JDK/JPMS - DataTypeConverter không có trong java.base, nhưng java.xml.ràng buộc, vì vậy bạn cần phải phụ thuộc một cách rõ ràng về nó khi chạy chương trình của bạn:

    java --add-modules java.xml.bind X509 stackoverflow.crt.pem 
    

    Nếu không, trên Java 9, bạn có được điều này khi bạn cố gắng chạy nó:

    Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter 
        at X509.getThumbPrint(X509.java:29) 
        at X509.main(X509.java:19) 
        Caused by: java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter 
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582) 
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185) 
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496) 
        ... 2 more 
    
  5. Get dự kiến đầu ra:

    47adb03649a2eb18f63ffa29790818349a99cab7 
    
+5

Cảm ơn bạn đã trả lời! Googling xung quanh tôi thấy rằng dấu vân tay thường được sử dụng như là một định danh duy nhất cho một chứng chỉ, do đó, nó không có vẻ là NET cụ thể. Dịch vụ web tôi đang gọi đang sử dụng dịch vụ này để tìm chứng chỉ trong cửa hàng của họ. –

+0

Dịch vụ web phải là máy chủ .NET. Tôi chưa thấy bất kỳ máy chủ nào khác sử dụng vân tay để lưu trữ chứng chỉ ứng dụng khách. .NET đã tạo ra rất nhiều tiện ích liên quan đến bảo mật, bạn cũng có thể gặp phải các vấn đề khác. Trừ khi khách hàng của bạn cần phải được nền tảng chéo, nó sẽ được dễ dàng hơn nhiều để viết khách hàng trong NET quá. –

+10

Dấu vân tay không phải là .Net độc quyền. Bạn đã thử kết nối với máy chủ bằng SSH chưa từng kết nối với trước chưa? Bạn sẽ thấy dấu vân tay của nó. Cửa hàng chứng chỉ cũng sẽ có dấu vân tay được liệt kê. – Henrik

5

Bạn có thể tạo ra các vân tay bằng cách sử dụng lệnh openssl, vì vậy ví dụ nếu bạn có định dạng pem Giấy chứng nhận trong một tập tin (file.txt)

thì:

cat file.txt | openssl x509 -sha1 -fingerprint - điều này sẽ tạo ra các vân tay cùng

+3

Trợ giúp đó với Java như thế nào? – Hiro2k

-9

Đây là một cách đơn giản hơn:

using System.Security.Cryptography.X509Certificates;  

X509Certificate2 xcert = new X509Certificate2("C:\some_cert.cerpub"); 
string certSubject = xcert.Subject; 
string certThumbprint = xcert.Thumbprint; 
+2

Đó không phải là Java :-) Tôi biết rất dễ dàng để có được trong. NET –

36

Sử dụng Apache Commons Codec bạn có thể làm:

DigestUtils.sha1Hex(cert.getEncoded()) 
+1

đẹp một lớp lót! – user882209

1

Một lớp lót sử dụng G chương trình Guava

String sha256AsHex = Hashing.sha256().hashBytes(x509Certificate.getEncoded()).toString(); 
+0

Để hoàn thành - thông thường SHA-1 ('Hashing.sha1()') được sử dụng như dấu vân tay (như đã thấy trong các câu trả lời khác). –

Các vấn đề liên quan