(2019-12-25 15:14:50 отредактировано MihCools)

Java экспорт сертификата с ruToken

Здравствуйте, далеко не специалист в данной теме, но нужно реализовать экспорт сертификата, почему нет вывода ?
Сделал следующее исходя из инструкций которые нашел:

ByteArrayInputStream configStream = new ByteArrayInputStream(pkcs11Config.getBytes());
Provider pkcs11Provider = new SunPKCS11(configStream);
Security.addProvider(pkcs11Provider);
Set<Provider.Service> services = pkcs11Provider.getServices();
System.out.println(services);
KeyStore keyStore =KeyStore.getInstance("PKCS11", pkcs11Provider);
keyStore.load(null, password);
System.out.println(keyStore.aliases()+ "   ali");
System.out.println(keyStore.getCertificate(keyStore.aliases().toString()));

Конфигурация провайдера взята из SDK

Вывод (за исключением информации о устройстве):
/n[SunPKCS11-provider: MessageDigest.SHA-512 -> sun.security.pkcs11.P11Digest
  aliases: [2.16.840.1.101.3.4.2.3, OID.2.16.840.1.101.3.4.2.3]
(CKM_SHA512), SunPKCS11-provider: Cipher.ARCFOUR -> sun.security.pkcs11.P11Cipher
  aliases: [RC4]
(CKM_RC4), SunPKCS11-provider: Cipher.DES/ECB/NoPadding -> sun.security.pkcs11.P11Cipher
(CKM_DES_ECB), SunPKCS11-provider: Signature.MD2withRSA -> sun.security.pkcs11.P11Signature
  aliases: [1.2.840.113549.1.1.2, OID.1.2.840.113549.1.1.2]
(CKM_RSA_PKCS), SunPKCS11-provider: Cipher.DES/CBC/NoPadding -> sun.security.pkcs11.P11Cipher
(CKM_DES_CBC), SunPKCS11-provider: KeyPairGenerator.RSA -> sun.security.pkcs11.P11KeyPairGenerator
(CKM_RSA_PKCS_KEY_PAIR_GEN), SunPKCS11-provider: Signature.SHA256withRSA -> sun.security.pkcs11.P11Signature
  aliases: [1.2.840.113549.1.1.11, OID.1.2.840.113549.1.1.11]
(CKM_SHA256_RSA_PKCS), SunPKCS11-provider: Cipher.DES/ECB/PKCS5Padding -> sun.security.pkcs11.P11Cipher
  aliases: [DES]
(CKM_DES_ECB), SunPKCS11-provider: SecretKeyFactory.DESede -> sun.security.pkcs11.P11SecretKeyFactory
(CKM_DES3_CBC), SunPKCS11-provider: SecretKeyFactory.DES -> sun.security.pkcs11.P11SecretKeyFactory
(CKM_DES_CBC), SunPKCS11-provider: Signature.SHA1withRSA -> sun.security.pkcs11.P11Signature
  aliases: [1.2.840.113549.1.1.5, OID.1.2.840.113549.1.1.5, 1.3.14.3.2.29]
(CKM_SHA1_RSA_PKCS), SunPKCS11-provider: SecretKeyFactory.ARCFOUR -> sun.security.pkcs11.P11SecretKeyFactory
  aliases: [RC4]
(CKM_RC4), SunPKCS11-provider: Signature.MD5withRSA -> sun.security.pkcs11.P11Signature
  aliases: [1.2.840.113549.1.1.4, OID.1.2.840.113549.1.1.4]
(CKM_MD5_RSA_PKCS), SunPKCS11-provider: KeyGenerator.ARCFOUR -> sun.security.pkcs11.P11KeyGenerator
  aliases: [RC4]
(CKM_RC4_KEY_GEN), SunPKCS11-provider: Cipher.RSA/ECB/PKCS1Padding -> sun.security.pkcs11.P11RSACipher
  aliases: [RSA]
(CKM_RSA_PKCS), SunPKCS11-provider: MessageDigest.MD5 -> sun.security.pkcs11.P11Digest
(CKM_MD5), SunPKCS11-provider: MessageDigest.SHA1 -> sun.security.pkcs11.P11Digest
  aliases: [SHA, SHA-1, 1.3.14.3.2.26, OID.1.3.14.3.2.26]
(CKM_SHA_1), SunPKCS11-provider: KeyFactory.RSA -> sun.security.pkcs11.P11RSAKeyFactory
(CKM_RSA_PKCS_KEY_PAIR_GEN), SunPKCS11-provider: Signature.SHA224withRSA -> sun.security.pkcs11.P11Signature
  aliases: [1.2.840.113549.1.1.14, OID.1.2.840.113549.1.1.14]
(CKM_RSA_PKCS), SunPKCS11-provider: Signature.SHA384withRSA -> sun.security.pkcs11.P11Signature
  aliases: [1.2.840.113549.1.1.12, OID.1.2.840.113549.1.1.12]
(CKM_SHA384_RSA_PKCS), SunPKCS11-provider: Signature.SHA512withRSA -> sun.security.pkcs11.P11Signature
  aliases: [1.2.840.113549.1.1.13, OID.1.2.840.113549.1.1.13]
(CKM_SHA512_RSA_PKCS), SunPKCS11-provider: Cipher.DESede/CBC/PKCS5Padding -> sun.security.pkcs11.P11Cipher
(CKM_DES3_CBC_PAD), SunPKCS11-provider: KeyGenerator.DESede -> sun.security.pkcs11.P11KeyGenerator
(CKM_DES3_KEY_GEN), SunPKCS11-provider: KeyGenerator.DES -> sun.security.pkcs11.P11KeyGenerator
(CKM_DES_KEY_GEN), SunPKCS11-provider: Cipher.DESede/ECB/NoPadding -> sun.security.pkcs11.P11Cipher
(CKM_DES3_ECB), SunPKCS11-provider: MessageDigest.SHA-384 -> sun.security.pkcs11.P11Digest
  aliases: [2.16.840.1.101.3.4.2.2, OID.2.16.840.1.101.3.4.2.2]
(CKM_SHA384), SunPKCS11-provider: Cipher.DESede/ECB/PKCS5Padding -> sun.security.pkcs11.P11Cipher
  aliases: [DESede]
(CKM_DES3_ECB), SunPKCS11-provider: Cipher.DES/CBC/PKCS5Padding -> sun.security.pkcs11.P11Cipher
(CKM_DES_CBC_PAD), SunPKCS11-provider: Cipher.DESede/CBC/NoPadding -> sun.security.pkcs11.P11Cipher
(CKM_DES3_CBC), SunPKCS11-provider: Mac.HmacSHA1 -> sun.security.pkcs11.P11MAC
  aliases: [1.2.840.113549.2.7, OID.1.2.840.113549.2.7]
(CKM_SHA_1_HMAC), SunPKCS11-provider: Cipher.RSA/ECB/NoPadding -> sun.security.pkcs11.P11RSACipher
(CKM_RSA_X_509), SunPKCS11-provider: Mac.HmacMD5 -> sun.security.pkcs11.P11MAC
(CKM_MD5_HMAC), SunPKCS11-provider: MessageDigest.SHA-256 -> sun.security.pkcs11.P11Digest
  aliases: [2.16.840.1.101.3.4.2.1, OID.2.16.840.1.101.3.4.2.1]
(CKM_SHA256), SunPKCS11-provider: SecureRandom.PKCS11 -> sun.security.pkcs11.P11SecureRandom
(SecureRandom), SunPKCS11-provider: KeyStore.PKCS11 -> sun.security.pkcs11.P11KeyStore
  aliases: [PKCS11-provider]
(KeyStore)]/n
java.util.Collections$3@3b95a09cali
null

(2019-12-25 21:40:34 отредактировано Евгений Мироненко)

Re: Java экспорт сертификата с ruToken

Здравствуйте.
Строка в вашем коде делает неведомое:

System.out.println(keyStore.getCertificate(keyStore.aliases().toString()));

keyStore.aliases().toString() имеет значение "java.util.Collections$3@3b95a09c". По коллекции надо итерироваться и доставать значения алиасов. Из keyStore сертификаты берутся по отдельным значениям алиасов.

Попробуйте так:

ByteArrayInputStream configStream = new ByteArrayInputStream(pkcs11Config.getBytes());
Provider pkcs11Provider = new SunPKCS11(configStream);
Security.addProvider(pkcs11Provider);
Set<Provider.Service> services = pkcs11Provider.getServices();
System.out.println(services);
KeyStore keyStore =KeyStore.getInstance("PKCS11", pkcs11Provider);
keyStore.load(null, password);
System.out.println(keyStore.aliases()+ "   ali");

for (Enumeration<String> aliases = keyStore.aliases(); aliases.hasMoreElements();) {
    String alias = aliases.nextElement();
    X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias);
    if (cert) {
        System.out.println(cert.toString());
    } else {
        System.out.println("Cert is null");
    }
}

(2019-12-25 22:13:42 отредактировано MihCools)

Re: Java экспорт сертификата с ruToken

Евгений Мироненко пишет:

Здравствуйте.
Строка в вашем коде делает неведомое:

System.out.println(keyStore.getCertificate(keyStore.aliases().toString()));

keyStore.aliases().toString() имеет значение "java.util.Collections$3@3b95a09c". По коллекции надо итерироваться и доставать значения алиасов. Из keyStore сертификаты берутся по отдельным значениям алиасов.

Попробуйте так:

ByteArrayInputStream configStream = new ByteArrayInputStream(pkcs11Config.getBytes());
Provider pkcs11Provider = new SunPKCS11(configStream);
Security.addProvider(pkcs11Provider);
Set<Provider.Service> services = pkcs11Provider.getServices();
System.out.println(services);
KeyStore keyStore =KeyStore.getInstance("PKCS11", pkcs11Provider);
keyStore.load(null, password);
System.out.println(keyStore.aliases()+ "   ali");

for (Enumeration<String> aliases = keyStore.aliases(); aliases.hasMoreElements();) {
    String alias = aliases.nextElement();
    X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias);
    if (cert) {
        System.out.println(cert.toString());
    } else {
        System.out.println("Cert is null");
    }
}

Спасибо большое что откликнулись ! Я уже с ума схожу не зная что делать, поэтому могу и чушь написать,   if (cert) java назвала неправильной, оставил System.out.println(cert.toString()+" cert"); - но эту строку вообще не выводит, но после нее код выполняется ...

Немного разобрался, как я понял - цикл вообще не запускается ....

Re: Java экспорт сертификата с ruToken

Пожалуйста, воспользуйтесь примерами из Рутокен SDK. Проект примеров для Java доступен по пути java/samples/JavaSamples.iml. Ближе всего к вашей задаче пример ru.rutoken.samples.sunJCA.RSA. Модифицированный до кода ниже, он выполняет вашу задачу.

package ru.rutoken.samples.sunJCA;

import ru.rutoken.samples.Constants;

import javax.crypto.Cipher;
import java.security.*;
import java.security.cert.X509Certificate;
import java.util.Enumeration;

public class RSA {
    public static void main(String[] args) {
        try {
            String config = "cfg/pkcs11.cfg";
            Provider sunPKCS11 = new sun.security.pkcs11.SunPKCS11(config);
            int pos = Security.addProvider(sunPKCS11);
            System.out.println("Provider Level: " + pos);

            // Авторизация на токен
            KeyStore ks = KeyStore.getInstance("PKCS11", sunPKCS11);
            ks.load(null, new String(Constants.DEFAULT_USER_PIN).toCharArray());

            // Поиск ключевой пары на токене (только если присутствует сертификат)
            Enumeration aliases = ks.aliases();
            String alias = null;
            while (aliases.hasMoreElements()) {
                alias = aliases.nextElement().toString();
                System.out.println("Alias:\n " + alias);
            }
            if (alias != null) {
                X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
                System.out.println("Certificate:\n " + cert);
            }
        } catch (Exception e) {
            System.out.println("Some error occurred. Error code: " + e.getMessage());
        }
    }
}

Если решение не работает, не могли бы уточнить, какими средствами сертификаты были записаны на токен?

Re: Java экспорт сертификата с ruToken

Евгений Мироненко пишет:

Пожалуйста, воспользуйтесь примерами из Рутокен SDK. Проект примеров для Java доступен по пути java/samples/JavaSamples.iml. Ближе всего к вашей задаче пример ru.rutoken.samples.sunJCA.RSA. Модифицированный до кода ниже, он выполняет вашу задачу.

package ru.rutoken.samples.sunJCA;

import ru.rutoken.samples.Constants;

import javax.crypto.Cipher;
import java.security.*;
import java.security.cert.X509Certificate;
import java.util.Enumeration;

public class RSA {
    public static void main(String[] args) {
        try {
            String config = "cfg/pkcs11.cfg";
            Provider sunPKCS11 = new sun.security.pkcs11.SunPKCS11(config);
            int pos = Security.addProvider(sunPKCS11);
            System.out.println("Provider Level: " + pos);

            // Авторизация на токен
            KeyStore ks = KeyStore.getInstance("PKCS11", sunPKCS11);
            ks.load(null, new String(Constants.DEFAULT_USER_PIN).toCharArray());

            // Поиск ключевой пары на токене (только если присутствует сертификат)
            Enumeration aliases = ks.aliases();
            String alias = null;
            while (aliases.hasMoreElements()) {
                alias = aliases.nextElement().toString();
                System.out.println("Alias:\n " + alias);
            }
            if (alias != null) {
                X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
                System.out.println("Certificate:\n " + cert);
            }
        } catch (Exception e) {
            System.out.println("Some error occurred. Error code: " + e.getMessage());
        }
    }
}

Если решение не работает, не могли бы уточнить, какими средствами сертификаты были записаны на токен?


Немного стыдно признаваться, но так и не понял как этот проект подключить к NetBeans, примерно это я уже пробовал, результат - все тот же.
Записывал не я, но у нас на предприятии используют КриптоПро и все что связано с ним.

Re: Java экспорт сертификата с ruToken

Может быть есть консольные утилиты которые могут выполнить данную задачу ?

Re: Java экспорт сертификата с ruToken

MihCools, возможно у вас контейнер КриптоПро?

Покажите, пожалуйста, скриншот Панели Управления Рутокен на вкладке сертификаты.

Re: Java экспорт сертификата с ruToken

Павел Анфимов пишет:

MihCools, возможно у вас контейнер КриптоПро?

Покажите, пожалуйста, скриншот Панели Управления Рутокен на вкладке сертификаты.

Здравствуйте, да Крипто-Про GOST R34.10-2001
Я так понимаю чтобы извлечь необходим провайдер Крипто-про ?

Re: Java экспорт сертификата с ruToken

MihCools пишет:

Здравствуйте, да Крипто-Про GOST R34.10-2001
Я так понимаю чтобы извлечь необходим провайдер Крипто-про ?

Экспорт сертификата можно произвести с помощью "Панели управления Рутокен" - вкладка "Сертификаты" или через "КриптоПро CSP".