如何使用Java获取证书文件的私钥

时间:2013-06-25 14:21:39

标签: java certificate x509certificate private-key public-key

我想确定一个公钥给出了一个证书文件(something.cer文件),这是我的Java代码:

public class X509Read {
private static String hex(String  binStr) {
    String newStr = new String();
        try {
            String hexStr = "0123456789ABCDEF";
            byte [] p = binStr.getBytes();
            for(int k=0; k < p.length; k++ ){
                int j = ( p[k] >> 4 )&0xF;
                newStr = newStr + hexStr.charAt( j );
                j = p[k]&0xF;
                newStr = newStr + hexStr.charAt( j ) + " ";
            }   
        } catch (Exception e) {
            System.out.println("Failed to convert into hex values: " + e);
        } 
        return newStr;
}
public static void main(String[] args) {
    String CA_Data[]=new String [15];
    String field;
    try{
        InputStream inStream = new FileInputStream("C:\\123.cer");
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate cert = 
            (X509Certificate)cf.generateCertificate(inStream);
        field=cert.getType().toString();
        CA_Data[0]=field;
        System.out.println("Type : "+field);
        field=Integer.toString(cert.getVersion());
        CA_Data[1]=field;
        System.out.println("Version : "+field);
        field=cert.getSubjectX500Principal().toString();
        CA_Data[2]=field;
        System.out.println("Name : "+field);
        field=cert.getSerialNumber().toString(16);
        CA_Data[3]=field;
        System.out.println("SerialNumber : "+field);
        field=cert.getSubjectAlternativeNames().toString();
        CA_Data[4]=field;
        System.out.println("SubjectAlternativeNames : "+field);
        field=cert.getNotBefore().toString();
        CA_Data[5]=field;
        System.out.println("NotBefore : "+field);
        field=cert.getNotAfter().toString();
        CA_Data[6]=field;
        System.out.println("NotAfter : "+field); 
        field=cert.getIssuerX500Principal().toString();
        CA_Data[7]=field;
        System.out.println("IssuerDN : "+field);
        field=cert.getSigAlgName().toString();
        CA_Data[8]=field;
        System.out.println("SigAlgName : "+field);
        byte [] tempPub = null;
        String sPub = null;
        RSAPublicKey pubkey = (RSAPublicKey) cert.getPublicKey();
        tempPub = pubkey.getEncoded();
        sPub = new String( tempPub );
        field=cert.getPublicKey().getAlgorithm();
        CA_Data[9]=field;
        System.out.println("Public Key Algorithm : " + field);
        field=hex(sPub);
        CA_Data[10]=field;
        System.out.println("Public key : \n" + field );        
        inStream.close();   
        }catch(Exception exception){ 
            exception.printStackTrace();
        }
    }
}

它获得了这些数据:30 EF BF BD 01 22 30 0D 06 09 2A EF BF BD 48 EF BF BD EF BF BD 0D 01 01 01 05 00 03 EF BF BD 01 0F 00 30 EF BF BD 01 0A 02 EF BF BD 01 01 00 CA BF 19 EF BF BD 24 EF BF BD 2F EF BF BD 6A EF BF BD EF BF BD 4C EF BF BD 2C EF BF BD 30 EF BF BD EF BF BD EF BF BD EF BF BD 7D EF BF BD 11 EF BF BD EF BF BD 7E EF BF BD 32 EF BF BD EF BF BD 42 73 EF BF BD EF BF BD 07 EF BF BD 15 EF BF BD 1D EF BF BD 00 39 33 66 4D 56 EF BF BD 67 EF BF BD EF BF BD EF BF BD 19 EF BF BD 17 64 EF BF BD 24 19 EF BF BD EF BF BD EF BF BD 15 EF BF BD EF BF BD C3 8C 3A EF BF BD EF BF BD EF BF BD 05 2D 3D C5 81 EF BF BD EF BF BD 48 71 EF BF BD 43 EF BF BD EF BF BD EF BF BD DE AE 20 EF BF BD EF BF BD 2B EF BF BD 1D D4 AE EF BF BD EF BF BD 25 EF BF BD 39 7B EF BF BD 70 0D 76 EF BF BD EF BF BD 7F 25 18 EF BF BD 22 EF BF BD EF BF BD EF BF BD 27 EF BF BD 0F EF BF BD EF BF BD EF BF BD DA 93 EF BF BD 0A 2C 03 3B EF BF BD 79 30 53 EF BF BD EF BF BD 26 30 EF BF BD 1D 3C 69 4C 20 EF BF BD 36 EF BF BD EF BF BD 41 7F EF BF BD 60 6B 58 EF BF BD EF BF BD EF BF BD 18 EF BF BD EF BF BD 01 6E 64 7F EF BF BD 5F 3B EF BF BD 7B 25 C9 83 43 15 EF BF BD 6F 78 EF BF BD 21 EF BF BD EF BF BD 38 59 EF BF BD EF BF BD EF BF BD EF BF BD 0B EF BF BD EF BF BD DE 9B 37 43 22 6A EF BF BD 15 28 EF BF BD 39 12 54 2B 38 4B EF BF BD 0A 43 67 0B 48 EF BF BD 59 02 60 57 EF BF BD 54 EF BF BD 6A 55 CE 91 EF BF BD 5A EF BF BD 78 76 66 13 EF BF BD 72 27 0A EF BF BD EF BF BD EF BF BD EF BF BD EF BF BD 0B 3E EF BF BD D2 9F EF BF BD 0E 4F EF BF BD EE B6 A5 5B EF BF BD 11 02 03 01 00 01

但是正确的公钥是(双击* .cer文件)

enter image description here

30 82 01 0a 02 82 01 01 00 ca bf 19 98 24 af 2f 8c 6a 94 e0 4c 9e 2c 86 30 9a 93 94 c5 7d f7 11 d8 e5 7e 8e 32 9d 90 42 73 99 ef 07 ed 15 a6 1d ff 00 39 33 66 4d 56 ee 67 9d 93 fd 19 f9 17 64 d9 24 19 de e3 d5 15 8a aa c3 8c 3a a7 d6 ec 05 2d 3d c5 81 da d0 48 71 d9 43 f1 e5 82 fc de ae 20 cc e3 2b c5 1d d4 ae eb a3 e3 93 25 e6 39 7b 8d 70 0d 76 b8 c0 7f 25 18 9d 22 b6 d8 ff 27 9e 0f f6 fe c4 da 93 9d 0a 2c 03 3b 80 79 30 53 c9 d0 26 30 9c 1d 3c 69 4c 20 80 36 a8 99 41 7f 99 60 6b 58 b0 84 a3 18 8b b8 01 6e 64 7f bc 5f 3b ce 7b 25 c9 83 43 15 af 6f 78 fa 21 c0 b7 38 59 90 b9 82 e0 0b f1 f6 de 9b 37 43 22 6a fb 15 28 da 39 12 54 2b 38 4b b8 0a 43 67 0b 48 9f 59 02 60 57 e6 89 54 dd 6a 55 ce 91 ad 5a f2 78 76 66 13 86 72 27 0a 94 82 a5 81 be 0b 3e fc d2 9f e0 0e 4f ba ee b6 a5 5b f9 11 02 03 01 00 01

我知道当我将Binary转换为Hex时,EF BF BD是替换字符。

  1. 如何获取正确的公钥?

  2. 如何获取私钥?

3 个答案:

答案 0 :(得分:5)

要获取公钥,只需使用getPublicKey()中的方法X509Certificate

无法从证书中检索私钥,因为它未包含在内。

答案 1 :(得分:3)

要扩展Uwe's answer,您看到不同值的原因是您对公钥数据的奇怪处理:

RSAPublicKey pubkey = (RSAPublicKey) cert.getPublicKey();
tempPub = pubkey.getEncoded();
sPub = new String( tempPub );
field=hex(sPub);
System.out.println("Public key : \n" + field );

在这里,您将从字节流创建一个字符串(从来不是一个好主意),然后对结果进行十六进制编码。难怪它看起来很奇怪!事实上,你的hex方法看起来很奇怪,可能应该被扔掉。

相反,试试这个:

RSAPublicKey pubkey = (RSAPublicKey) cert.getPublicKey();
field = DatatypeConverter.printHexBinary(pubkey.getEncoded());
System.out.println("Public key : \n" + field );

如果您使用的是Java 5或更低版本,则Google无法使用DatatypeConverter作为正常的字节到十六进制函数。

答案 2 :(得分:0)

私钥存储在身份验证服务器上,客户端不应该读取该密钥。