Java 使用X509 Thumprint验证证书

Java 使用X509 Thumprint验证证书,java,x509certificate,Java,X509certificate,我已成功阅读X509证书的指纹。是否可以使用指纹值验证证书?我只需要一个安全的服务器证书验证 public class certificate { public static void main(String[] args) { FileInputStream is; try { is = new FileInputStream("certificate.crt"); CertificateFact

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

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();
    }      
公共类证书{
公共静态void main(字符串[]args){
FileInputStream是;
试一试{
is=新文件输入流(“certificate.crt”);
CertificateFactory x509CertFact=CertificateFactory.getInstance(“X.509”);
X509Certificate cert=(X509Certificate)x509CertFact.generateCertificate(is);
字符串指纹=getThumbPrint(证书);
System.out.println(“指纹:+指纹”);
}catch(filenotfounde异常){
e、 printStackTrace();
}捕获(证书例外e){
e、 printStackTrace();
}捕获(无算法异常){
e、 printStackTrace();
}
}    
公共静态字符串打印(X509证书证书)
抛出NoSuchAlgorithmException、CertificateEncodingException{
MessageDigest md=MessageDigest.getInstance(“SHA-1”);
字节[]der=cert.getEncoded();
md.update(der);
字节[]摘要=md.digest();
返回hexify(摘要);
}
公共静态字符串hexify(字节[]){
char[]hexDigits={'0','1','2','3','4','5','6','7',
‘8’、‘9’、‘a’、‘b’、‘c’、‘d’、‘e’、‘f’};
StringBuffer buf=新的StringBuffer(bytes.length*2);
对于(int i=0;i>4]);
追加(十六进制数字[bytes[i]&0x0f]);
}
返回buf.toString();
}      
}

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


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

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();
    }      
请记住,如果你正在验证谷歌(和其他网站),那么指纹大约每30天就会改变一次。这是因为谷歌使用短期证书(30天到期)来管理撤销列表(CRL)。但是,Google重新认证相同的公钥,因此您可以锁定公钥而不是证书

有关固定的更多信息,请参阅OWASP

此外,IETF还有一项倡议


最后,您可以通过安全多样化战略将所有这些提升到下一个级别。参见Peter Gutmann。

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

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


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

即使对“长寿”证书比较证书哈希也不足以验证证书。正确的证书验证包括几个步骤,包括OCSP和CRL检查。