Как получить закрытый ключ по файлу сертификата с помощью Java

Я хочу определить, какой открытый ключ получает файл сертификата (файл 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)

введите здесь описание изображения

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

Я знаю, что EF BF BD является символом замены, когда я преобразовываю двоичный файл в шестнадцатеричный.

  1. Как получить правильный открытый ключ?

  2. Как получить приватный ключ?


person user2452153    schedule 25.06.2013    source источник
comment
Вы не можете. Закрытого ключа там нет. Иначе это не было бы приватным, верно?   -  person user207421    schedule 26.06.2013


Ответы (3)


Чтобы расширить ответ Уве, причиной, по которой вы видите разные значения, является ваша странная обработка данных открытого ключа:

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 недоступен.

person Duncan Jones    schedule 25.06.2013
comment
@user2452153 user2452153 как я могу получить закрытый ключ от сертификации в коде Java? - person Shaaban Ebrahim; 19.10.2017

Чтобы получить открытый ключ, просто используйте метод getPublicKey() из X509Certificate.

Закрытый ключ не может быть извлечен из сертификата, так как он не включен.

person Uwe Plonus    schedule 25.06.2013

Закрытый ключ хранится на сервере аутентификации, и клиенты не должны его читать.

person user3657056    schedule 26.06.2014