Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

2 Страницы12>
Опции
К последнему сообщению К первому непрочитанному
Offline Анатолий В.  
#1 Оставлено : 19 февраля 2018 г. 19:48:09(UTC)
Анатолий В.

Статус: Новичок

Группы: Участники
Зарегистрирован: 19.02.2018(UTC)
Сообщений: 9
Российская Федерация
Откуда: Москва

Здравствуйте.
Реализую функционал валидации подписи и сертификата. В наличии есть данные и сама подпись.
Сертификат был выпущен вашим тестовым УЦ. Нужно проверить с помощью OCSP.

Стучусь по урлу http://testca.cryptopro.ru/ocsp/ocsp.srf, мне возвращается CertStatus._UNKNOWN

Я в замешательстве. Нормальная ли эта ситуация?
Спасибо.
Offline basid  
#2 Оставлено : 19 февраля 2018 г. 21:08:56(UTC)
basid

Статус: Активный участник

Группы: Участники
Зарегистрирован: 21.11.2010(UTC)
Сообщений: 1,044

Сказал(а) «Спасибо»: 7 раз
Поблагодарили: 141 раз в 127 постах
"Ваших УЦ" у КриптоПро три штуки: два "промышленных" и один тестовый.
Сертификат точно выпущен тестовым УЦ, к сервису которого вы обращаетесь?
Online Андрей Писарев  
#3 Оставлено : 19 февраля 2018 г. 22:24:41(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 12,713
Мужчина
Российская Федерация

Сказал «Спасибо»: 500 раз
Поблагодарили: 2052 раз в 1592 постах
Здравствуйте.

Предлагаю свериться:

откройте клиентский сертификат и посмотрите, что в нём прописано:
1) в CDP указан этот url?
2) идентификатор ключа ЦС = 15 31 7c b0 8d 1a de 66 d7 15 9c 49 52 97 17 24 b9 01 7a 83 ?
Техническую поддержку оказываем тут
Наша база знаний
Offline Анатолий В.  
#4 Оставлено : 20 февраля 2018 г. 10:32:53(UTC)
Анатолий В.

Статус: Новичок

Группы: Участники
Зарегистрирован: 19.02.2018(UTC)
Сообщений: 9
Российская Федерация
Откуда: Москва

1) Да, URL именно этот - см.скрин.
2) Да, идентификатор этот - см.скрин.
q1.png (39kb) загружен 37 раз(а).

q2.png (17kb) загружен 39 раз(а).

q4.png (17kb) загружен 37 раз(а).

q3.png (21kb) загружен 35 раз(а).
Online Андрей Писарев  
#5 Оставлено : 20 февраля 2018 г. 10:36:07(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 12,713
Мужчина
Российская Федерация

Сказал «Спасибо»: 500 раз
Поблагодарили: 2052 раз в 1592 постах
Автор: Анатолий В. Перейти к цитате

Реализую функционал валидации подписи и сертификата. В наличии есть данные и сама подпись.
Сертификат был выпущен вашим тестовым УЦ. Нужно проверить с помощью OCSP.


Пример кода можете предоставить, в котором получаете CertStatus._UNKNOWN?
Техническую поддержку оказываем тут
Наша база знаний
Offline Анатолий В.  
#6 Оставлено : 20 февраля 2018 г. 10:45:45(UTC)
Анатолий В.

Статус: Новичок

Группы: Участники
Зарегистрирован: 19.02.2018(UTC)
Сообщений: 9
Российская Федерация
Откуда: Москва

Из подписи и самих исходных данных достаю сертификат и валидирую подпись:

Код:
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cms.*;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.encoders.Base64;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

public class VerifySignature {

    private static final String BC = "BC";

    public static void main(String[] args) throws Exception {

        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><tag1><tag2></tag2><tag3></tag3><tagN></tagN></tag1>";
        String sig = "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";

        Security.addProvider(new BouncyCastleProvider());
        CMSProcessable signedContent = new CMSProcessableByteArray(xml.getBytes(StandardCharsets.UTF_8));
        InputStream is = new ByteArrayInputStream(Base64.decode(sig.getBytes()));
        CMSSignedData cms = new CMSSignedData(signedContent, is);
        Store store = cms.getCertificates();

        SignerInformationStore signerStore = cms.getSignerInfos();
        Collection signers = signerStore.getSigners();
        for (Object s : signers) {
            SignerInformation signer = (SignerInformation) s;
            Collection certCollection = store.getMatches(signer.getSID());
            Iterator certIterator = certCollection.iterator();
            X509CertificateHolder certHolder = (X509CertificateHolder) certIterator.next();
            X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certHolder);

            try {
                if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))) {
                    System.err.println("Verified");
                    System.err.println(cert);
                } else {
                    System.err.println("Failed");
                }
            } catch (CMSSignerDigestMismatchException e) {
                System.err.println();
            }
            OcspVerifier ocspVerifier = new OcspVerifier();
            String ocspUrl = "http://testca.cryptopro.ru/ocsp/ocsp.srf";
            ocspVerifier.process(ocspUrl, cert);
        }
    }
}


Затем пробую проверить валидность сертификата с помощью OCSP:

Код:
import com.objsys.asn1j.runtime.*;
import org.apache.xml.security.utils.Base64;
import ru.CryptoPro.JCP.ASN.PKIX1Explicit88.AlgorithmIdentifier;
import ru.CryptoPro.JCP.ASN.PKIX1Explicit88.CertificateSerialNumber;
import ru.CryptoPro.JCP.ASN.PKIXOCSP.*;
import ru.CryptoPro.JCP.JCP;
import ru.CryptoPro.JCP.params.OID;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;

public class OcspVerifier {

    private static void checkServerResponse(OCSPResponse response, BigInteger certSerialNumber) throws Asn1Exception, IOException {
        OCSPResponseStatus responseStatus = response.responseStatus;
        int status = responseStatus.value;

        if (status != OCSPResponseStatus.successful) {
            System.err.println("invalid status");
        }

        ResponseBytes bytes = response.responseBytes;
        byte[] responseValue = bytes.response.value;

        Asn1BerDecodeBuffer decoded = new Asn1BerDecodeBuffer(responseValue);
        BasicOCSPResponse basicOCSPResponse = new BasicOCSPResponse();
        basicOCSPResponse.decode(decoded);

        _SeqOfSingleResponse seqOfSingleResponse = basicOCSPResponse.tbsResponseData.responses;
        SingleResponse[] singleResponses = seqOfSingleResponse.elements;

        for (SingleResponse singleResponse : singleResponses) {
            ReqCert reqCert = singleResponse.reqCert;
            CertID certId = (CertID) reqCert.getElement();
            CertificateSerialNumber ssn = certId.serialNumber;
            BigInteger bgSerial = ssn.value;

            if (bgSerial.equals(certSerialNumber)) {
                CertStatus certStatus = singleResponse.certStatus;
                System.err.println("Client certificate found, status is " + certStatus.getElemName() + "\n");
                if (certStatus.getChoiceID() == CertStatus._GOOD) {
                } else if (certStatus.getChoiceID() == CertStatus._REVOKED) {
                } else if (certStatus.getChoiceID() == CertStatus._UNKNOWN) {
                }
                break;
            }
        }
    }

    public static void process(String ocspUrl, X509Certificate cert) throws Exception {
        OCSPRequest ocspRequest = createOCSPRequest(cert);
        Asn1DerEncodeBuffer encodedData = new Asn1DerEncodeBuffer();
        ocspRequest.encode(encodedData);
        byte[] data = encodedData.getMsgCopy();

        HttpURLConnection con = call(ocspUrl, data);
        OCSPResponse ocspResponse = new OCSPResponse();
        Asn1DerDecodeBuffer asn1DerDecodeBuffer = new Asn1DerDecodeBuffer(getData(con));
        ocspResponse.decode(asn1DerDecodeBuffer);
        System.err.println("ocspResponse.responseStatus.value: " + ocspResponse.responseStatus.value);

        String response = Base64.encode(ocspResponse.responseBytes.response.value);
        System.err.println(response);

        checkServerResponse(ocspResponse, cert.getSerialNumber());
    }

    private static OCSPRequest createOCSPRequest(X509Certificate cert) throws Exception {
        TBSRequest tbsRequest = new TBSRequest();
        tbsRequest.version = new OCSPVersion(0);
        tbsRequest.requestorName = null;
        tbsRequest.requestList = createRequestList(new X509Certificate[]{cert});
        return new OCSPRequest(tbsRequest);
    }

    private static _SeqOfRequest createRequestList(X509Certificate[] certs) throws Exception {
        _SeqOfRequest requestList = new _SeqOfRequest(certs.length);
        for (int i = 0; i < certs.length; i++) {
            X509Certificate cert = certs[i];
            CertID certID = new CertID();
            certID.hashAlgorithm = getHashAlgId();
            certID.issuerNameHash = new Asn1OctetString(digest(cert.getIssuerX500Principal().getEncoded()));
            certID.issuerKeyHash = new Asn1OctetString(digest(cert.getPublicKey().getEncoded()));
            certID.serialNumber = new CertificateSerialNumber(cert.getSerialNumber());

            ReqCert reqCert = new ReqCert();
            reqCert.set_certID(certID);
            requestList.elements[i] = new Request(reqCert);
        }
        return requestList;
    }

    private static byte[] getData(HttpURLConnection connection) throws IOException {
        byte[] data = new byte[connection.getContentLength()];
        try (InputStream is = connection.getInputStream()) {
            is.read(data);
        }
        return data;
    }

    private static HttpURLConnection call(String ocspUrl, byte[] data) throws IOException {
        HttpURLConnection con = (HttpURLConnection) new URL(ocspUrl).openConnection();
        con.setDoOutput(true);
        con.setDoInput(true);
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/ocsp-request");
        con.setRequestProperty("Accept", "application/ocsp-response");
        con.setRequestProperty("Content-length", String.valueOf(data.length));

        System.err.println("content-length:" + data.length + " bytes");

        try (OutputStream out = con.getOutputStream()) {
            out.write(data);
            out.flush();
        }

        if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
            System.err.println(con.getResponseMessage());
            Map<String, List<String>> headerFields = con.getHeaderFields();
            for (String s : headerFields.keySet()) {
                System.err.println("key:" + s + " val:" + headerFields.get(s));
            }
            throw new IOException("Received HTTP error: " + con.getResponseCode() + " - " + con.getResponseMessage());
        }
        return con;
    }

    private static AlgorithmIdentifier getHashAlgId() {
        AlgorithmIdentifier hashAlgId = new AlgorithmIdentifier(new OID(JCP.GOST_DIGEST_OID).value);
        hashAlgId.parameters = new Asn1Null();
        return hashAlgId;
    }

    private static byte[] digest(byte[] data) throws NoSuchAlgorithmException, NoSuchProviderException {
        MessageDigest digest = MessageDigest.getInstance(JCP.GOST_DIGEST_NAME, JCP.PROVIDER_NAME);
        digest.update(data);
        return digest.digest();
    }
}
Offline Евгений Афанасьев  
#7 Оставлено : 20 февраля 2018 г. 13:21:31(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 3,926
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 691 раз в 652 постах
Здравствуйте.
Попробуйте в createRequestList использовать:
Код:

OCSPRequest createRequestList(X509Certificate client, X509Certificate issuer /*издатель*/) {

  ...

  X500Principal issuerName = issuer.getSubjectX500Principal();
  byte[] issuerNameHash = digest(issuerName.getEncoded());

  PublicKey issuerKey = issuer.getPublicKey();
  byte[] encodedKey = issuerKey.getEncoded();

  Asn1BerDecodeBuffer buf = new Asn1BerDecodeBuffer(encodedKey);
  SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo();
        
  keyInfo.decode(buf);
  byte[] clearKey = keyInfo.subjectPublicKey.value;
  byte[] issuerKeyHash = digest(clearKey);

  CertificateSerialNumber ssn = new CertificateSerialNumber(client.getSerialNumber());
  CertID certId = new CertID(getHashAlgId(), issuerNameHash, issuerKeyHash, ssn);

  ...

}

Отредактировано пользователем 20 февраля 2018 г. 13:23:12(UTC)  | Причина: Не указана

Offline Анатолий В.  
#8 Оставлено : 20 февраля 2018 г. 13:37:50(UTC)
Анатолий В.

Статус: Новичок

Группы: Участники
Зарегистрирован: 19.02.2018(UTC)
Сообщений: 9
Российская Федерация
Откуда: Москва

Автор: afev Перейти к цитате
X509Certificate issuer


afev, здравствуйте. Я не понимаю, что такое issuer и откуда мне его взять.
Подскажите, пожалуйста.
Online Андрей Писарев  
#9 Оставлено : 20 февраля 2018 г. 13:46:58(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 12,713
Мужчина
Российская Федерация

Сказал «Спасибо»: 500 раз
Поблагодарили: 2052 раз в 1592 постах
issuer - это сертификата издателя - сертификат УЦ.
Техническую поддержку оказываем тут
Наша база знаний
Offline Анатолий В.  
#10 Оставлено : 20 февраля 2018 г. 14:07:56(UTC)
Анатолий В.

Статус: Новичок

Группы: Участники
Зарегистрирован: 19.02.2018(UTC)
Сообщений: 9
Российская Федерация
Откуда: Москва

Я формирую OCSPRequest так:

Код:
X509Certificate cert = //это клиентский сертификат, который я получил из подписанных данных + исходных данных;

CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
byte[] encodedRootCert = GostCertificateRequest.getEncodedRootCert("http://www.cryptopro.ru/certsrv/");
X509Certificate issuer = (X509Certificate) certificateFactory
                                             .generateCertificate(new ByteArrayInputStream(encodedRootCert));

createOCSPRequest(cert, issuer);



private static OCSPRequest createOCSPRequest(X509Certificate cert, X509Certificate issuer) throws Exception {
        TBSRequest tbsRequest = new TBSRequest();
        tbsRequest.version = new OCSPVersion(0);
        tbsRequest.requestorName = null;

        _SeqOfRequest requestList = new _SeqOfRequest(1);

        X500Principal issuerName = issuer.getSubjectX500Principal();
        byte[] issuerNameHash = digest(issuerName.getEncoded());

        PublicKey issuerKey = issuer.getPublicKey();
        byte[] encodedKey = issuerKey.getEncoded();

        Asn1BerDecodeBuffer buf = new Asn1BerDecodeBuffer(encodedKey);
        SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo();

        keyInfo.decode(buf);
        byte[] clearKey = keyInfo.subjectPublicKey.value;
        byte[] issuerKeyHash = digest(clearKey);

        CertificateSerialNumber ssn = new CertificateSerialNumber(cert.getSerialNumber());
        CertID certID = new CertID(getHashAlgId(), issuerNameHash, issuerKeyHash, ssn);

        ReqCert reqCert = new ReqCert();
        reqCert.set_certID(certID);
        requestList.elements[0] = new Request(reqCert);

        tbsRequest.requestList = requestList;
        return new OCSPRequest(tbsRequest);
    }



У меня есть ТРИ строки с различными исходными данными (XML) и ТРИ стринги с подписями. То есть есть 3 пары данных с их подписями.
Две случая - это подписи тестового УЦ КриптоПро.
Третий случай - это сертификат "Электронной Москвы".

Во всех трех случаях мне вернулся статус CertStatus._GOOD. Это же неправильно?
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
2 Страницы12>
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.