使用X509指纹验证证书

时间:2014-03-25 07:44:20

标签: java x509certificate

我已成功阅读X509证书的ThumbPrint。是否可以使用指纹值验证证书?我只想要一个安全的服务器证书验证。

public class certificate {    

    public static void main(String[] args) {
        FileInputStream is;
        try {
            is = new FileInputStream("certificate.crt");
            CertificateFactory x509CertFact = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate)x509CertFact.generateCertificate(is);

            String thumbprint = getThumbPrint(cert);
            System.out.println("Thumb Print : " + thumbprint);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }    

    public 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();
        return hexify(digest);
    }

    public static String hexify (byte bytes[]) {
        char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', 
                '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        StringBuffer buf = new StringBuffer(bytes.length * 2);

        for (int i = 0; i < bytes.length; ++i) {
            buf.append(hexDigits[(bytes[i] & 0xf0) >> 4]);
            buf.append(hexDigits[bytes[i] & 0x0f]);
        }

        return buf.toString();
    }      

}

2 个答案:

答案 0 :(得分:1)

  

是否可以使用指纹值验证证书?


  

我只想要一个安全的服务器证书验证。

请记住,如果您要验证Google(和其他网站),那么指纹将每30天更改一次。这是因为Google使用短期证书(30天到期)来保持撤销列表(CRL)的可管理性。但是,Google会重新识别相同的公钥,因此您可以固定公钥而不是证书。

有关固定的更多信息,请参阅OWASP&#39; Certificate and Public Key Pinning

此外,IETF有一项倡议Public Key Pinning Extension for HTTP

最后,您可以通过安全多元化策略将所有这些提升到新的水平。见Peter Gutmann的Engineering Security

答案 1 :(得分:0)

证书的摘要本身没有任何意义。我不知道任何基于证书的方案使用SHA-1或证书正文的任何​​其他类型的摘要作为验证证书的唯一方法。

java.security.cert.Certificate API有一个定义明确的方法来使用公钥来验证证书,该公钥应该属于颁发证书的机构(这导致了证书链的概念)。

正确的证书验证应使用java.security.cert.CertPathValidator API并提供应检查其有效性的证书或证书链以及包含可信CA根的信任库。验证的核心思想是检查链中的每个证书是否使用链中下一个项目的公钥进行签名,以及最后一个证书是否为可信根。