Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Работа с сертификатами


Автор: regen 26.4.2007, 14:43
Добрый день.

Пытаюсь сейчас разобраться как работать из под Java с сертификатами.
Интересуют следующий аспекты:
1) как генерировать сертификаты
2) как подписывать с помощью сертификата
3) как создавать списки отзыва сертификатов

Не поможете?

Был бы очень благодарен за примеры.  smile 

Заранее благодарю.

Автор: powerOn 26.4.2007, 19:21
читай http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/keytool.html по утилите keytool. там все описано.

Автор: Alexandr87 27.4.2007, 07:34
Цитата(powerOn @  26.4.2007,  22:21 Найти цитируемый пост)
читай доку по утилите keytool. там все описано. 

думаю, человек имел ввиду несколько другое, а именно, как программно работать с сертификатами.


Цитата(regen @  26.4.2007,  17:43 Найти цитируемый пост)
1) как генерировать сертификаты

На сколько мне известно, встроенных решений нет, необходимо использовать сторонние библиотеки. Например в библиотеке bouncycastle, есть такая возможность. http://www.bouncycastle.org/docs/docs1.5/org/bouncycastle/x509/X509V3CertificateGenerator.html
Cоветую посмотреть весь пакет org.bouncycastle.x509


Цитата(regen @  26.4.2007,  17:43 Найти цитируемый пост)
2) как подписывать с помощью сертификата

C помощью сертификата ничего подписать нельзя, с помощью сертификат можно только проверить подпись. Подпись вырабатывается используя закрытый(прайвит) ключ ключевой пары, сертификат содержит только открытый. В составе j2se, есть классы для формирования подписи для байтовых массивов.  Сморите класс java.security.Signature и другие классы данного пакета.


Цитата(regen @  26.4.2007,  17:43 Найти цитируемый пост)
3) как создавать списки отзыва сертификатов

Опять таки стандартных средств я не знаю, но все в тойже библиотеке bouncycastle, все в тоже пакете org.bouncycastle.x509 есть класс для формирования списков отзыва.

Автор: regen 27.4.2007, 14:08
Не подкините ли ссылки на примеры использования bouncycastle для работы с сертификатами ?

Автор: Alexandr87 27.4.2007, 19:52
Цитата(regen @  27.4.2007,  17:08 Найти цитируемый пост)
Не подкините ли ссылки на примеры использования bouncycastle для работы с сертификатами ? 

Вверху была ссылка на javadoc, имена функций говорят сами за себя.

Вот небольшой примерчик набросал.
В конструкторе генерируется пара ключей и самоподписанный сертификат на эту ключевую пару. (Своего рода корневой сертификат)
Далее с помощью метода generateCertificate, вы можете пользуясь сгенерированной в конструкторе ключевой парой, создать новые сертификаты на передаваемый паблик кей.

В методе main также есть код, демонстрирующий, как выработать подпись для массива байтов.

Будут вопросы задавайте.



Код

import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.cert.X509Certificate;
import java.util.Date;
import org.bouncycastle.asn1.x509.X509Name;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.x509.X509V3CertificateGenerator;


public class CertificatesExample {
    
    public final static String signatureAlgorithm = "SHA1withRSA";
    public final static long validPeriod = 1000*60*60*24*10;
    
    private KeyPair rootKeyPair;
    private X509Certificate rootCertificate;
    
    private BigInteger snCounter;
    
    /** Creates a new instance of Certificates */
    public CertificatesExample()
    throws Exception {
        
        snCounter = new BigInteger("0");
        
        
        Security.addProvider(new BouncyCastleProvider());
        
        // generate and save root KeyPair
        KeyPairGenerator kpGenerator = KeyPairGenerator.getInstance("RSA");
        rootKeyPair = kpGenerator.generateKeyPair();
        
        X509Name rootDN = new X509Name("CN=ROOT CA C=KZ O=HomeCA");
        
        
        // create selfsigned root certificate
        X509V3CertificateGenerator certGenerator =
                new X509V3CertificateGenerator();
        certGenerator.setIssuerDN(rootDN);
        certGenerator.setSubjectDN(rootDN);
        certGenerator.setSignatureAlgorithm(signatureAlgorithm);
        certGenerator.setSerialNumber(getNextSerialNumber());
        certGenerator.setNotBefore(new Date(System.currentTimeMillis()));
        certGenerator.setNotAfter(
                new Date(System.currentTimeMillis() + validPeriod));
        certGenerator.setPublicKey(rootKeyPair.getPublic());
        
        rootCertificate = certGenerator.generate(rootKeyPair.getPrivate());
        
    }
    
    public X509Certificate getRootCertificate() {
        return rootCertificate;
    }
    
    public X509Certificate generateCertificate(PublicKey pubKey, String name)
    throws Exception {
        
        X509V3CertificateGenerator certGenerator = 
                new X509V3CertificateGenerator();

        certGenerator.setIssuerDN(rootCertificate.getSubjectX500Principal());
        certGenerator.setSubjectDN(new X509Name(name));
        certGenerator.setSignatureAlgorithm(signatureAlgorithm);
        certGenerator.setSerialNumber(getNextSerialNumber());
        certGenerator.setNotBefore(new Date(System.currentTimeMillis()));
        certGenerator.setNotAfter(
                new Date(System.currentTimeMillis() + validPeriod));
        certGenerator.setPublicKey(pubKey);
        
        
        X509Certificate resCert = 
                certGenerator.generate(rootKeyPair.getPrivate());
        
        
        return resCert;
    }
    
    private synchronized BigInteger getNextSerialNumber() {
        snCounter = snCounter.add(new BigInteger("1"));
        return snCounter;
    }
    
    public static void main(String args[])
    throws Exception {
        
        CertificatesExample examp = new CertificatesExample();
        System.out.println(examp.getRootCertificate());
        
        // generate antoher key pair
        KeyPairGenerator kpGenerator = KeyPairGenerator.getInstance("RSA");
        KeyPair keyPair = kpGenerator.generateKeyPair();
        
        // generate certificate, with root issuer
        X509Certificate myCert = examp.generateCertificate(
                keyPair.getPublic(), "CN=Alexandr");
        System.out.println(myCert);
        
        // sign data
        byte dataToSign[] = "data to sign".getBytes();
        
        Signature signature = Signature.getInstance("SHA1withRSA");
        signature.initSign(keyPair.getPrivate());
        signature.update(dataToSign);
        byte sign[] = signature.sign();
        
        // verify signature
        signature.initVerify(myCert);
        signature.update(dataToSign);
        boolean isSignValid = signature.verify(sign);
        
        if (isSignValid) {
            System.out.println("OK");
        } else {
            System.out.println("FAIL");
        }

    }
    
}




Автор: regen 3.5.2007, 11:14
Alexandr87, спасибо большое за пример. Всё работает замечательно. 

Однако появился вопрос: сгенерированный сертификат находится в памяти. Как можно его экспортировать в файл? (стандартный файл сертификата, *.crt)? Пробовал через FileWriter записать - не получилось.

//-------------------------
Только что сам нашёл ответ на свой вопрос. Необходимо использовать PEMWriter. =)
Кстати, в Вашем коде закралась ошибка. Информацию о субъекте надо писать через запятую, т.е. 
Код

...
X509Name rootDN = new X509Name("C=RU, CN=Igor Gorshkov");
...

А так, всё замечательно. Теперь только осталось разобраться мне с CRL и всё вообще хорошо будет.
Спасибо вам!
//-------------------------

Автор: cube 20.7.2007, 14:12
Я только-только разбираюсь в сертификатах, поэтому может говорю глупости, но просто не понимаю

У меня программа читает сертификат с файла например certificate.crt, мне нужно удостоверится что это мой сертификати дальше делать какие нибудь дейтсвия, например если не мой то выходить из программы, если мой - то работать дальше... или что-то вроде этого...

Т.е. меня интересует проверка на подлинность... как?

Автор: regen 23.7.2007, 10:32
Да. Проверка на подлинность. Методов как это делать много, так что выбор большой =)

Автор: cube 24.7.2007, 23:10
Цитата(regen @ 23.7.2007,  10:32)
Да. Проверка на подлинность. Методов как это делать много, так что выбор большой =)

Покажи пример, если нетрудно...

Автор: YuG 25.7.2007, 11:55
2Alexandr87
Большое спасибо за библиотечку и за пример.

Автор: regen 25.7.2007, 15:18
2 cube
Если есть секретный ключ (а он должен быть для проверки на подлинность сертификата), то можно подписать массив байтов этим ключом и проверить открытым, если подпись верна, то и открытый ключ верен (см. пример Alexandr87-а, там всё есть)
       

Автор: Alexandr87 26.7.2007, 05:40
YuG, пожалста.

cube, опишите задачи более конкретно, не совсем понятно, что вкладывается в определение проверка на подлинность. Аутентификация?

Автор: regen 31.7.2007, 09:31
Alexandr87, я так понял что в словосочетание "проверка на подлинность" в данном контексте вкладывается что-то такое:
1) сертификат ведь как правило размещается в репозитории центра сертификации
2) владелец сертификата зачем-то берёт экземпляр сертификата не со своего носителя, а именно из репозитория ЦС
3) затем дабы быть уверенным что не была проведена атака "man in the midle" он проверяет на соответствие открытого ключа и закрытого

Такое в принципе возможно, но странно и непонятно... Если хранится закрытый ключ (а он должен хранится), то сертификат и подавно должен. Иначе всё теряет смысл.
Вообщем как-то так...

Автор: Alexandr87 31.7.2007, 10:14
regen, вобсчем, как-то вы это не так поняли smile Есть более логически подходящие определения проверка подлинности.

Цитата(regen @  31.7.2007,  12:31 Найти цитируемый пост)
3) затем дабы быть уверенным что не была проведена атака "man in the midle" он проверяет на соответствие открытого ключа и закрытого

Э, не совсем понятно, как в данном случае может быть проведена атака "man in the midle" - сертификат с подписью доверенного CA (а это значит, что открытый ключ этого CA должен хранится у вас) и есть гарант того, что сертификат валиден.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)