Статус: Новичок
Группы: Участники
Зарегистрирован: 19.02.2018(UTC) Сообщений: 9 Откуда: Москва
|
Здравствуйте. Реализую функционал валидации подписи и сертификата. В наличии есть данные и сама подпись. Сертификат был выпущен вашим тестовым УЦ. Нужно проверить с помощью OCSP. Стучусь по урлу http://testca.cryptopro.ru/ocsp/ocsp.srf, мне возвращается CertStatus._UNKNOWN Я в замешательстве. Нормальная ли эта ситуация? Спасибо.
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 21.11.2010(UTC) Сообщений: 1,045
Сказал(а) «Спасибо»: 7 раз Поблагодарили: 141 раз в 127 постах
|
"Ваших УЦ" у КриптоПро три штуки: два "промышленных" и один тестовый. Сертификат точно выпущен тестовым УЦ, к сервису которого вы обращаетесь?
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 12,721 Сказал «Спасибо»: 500 раз Поблагодарили: 2055 раз в 1595 постах
|
Здравствуйте.
Предлагаю свериться:
откройте клиентский сертификат и посмотрите, что в нём прописано: 1) в CDP указан этот url? 2) идентификатор ключа ЦС = 15 31 7c b0 8d 1a de 66 d7 15 9c 49 52 97 17 24 b9 01 7a 83 ? |
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 19.02.2018(UTC) Сообщений: 9 Откуда: Москва
|
1) Да, URL именно этот - см.скрин. 2) Да, идентификатор этот - см.скрин. q1.png (39kb) загружен 37 раз(а). q2.png (17kb) загружен 39 раз(а). q4.png (17kb) загружен 37 раз(а). q3.png (21kb) загружен 35 раз(а).
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 12,721 Сказал «Спасибо»: 500 раз Поблагодарили: 2055 раз в 1595 постах
|
Автор: Анатолий В. Реализую функционал валидации подписи и сертификата. В наличии есть данные и сама подпись. Сертификат был выпущен вашим тестовым УЦ. Нужно проверить с помощью OCSP. Пример кода можете предоставить, в котором получаете CertStatus._UNKNOWN? |
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 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();
}
}
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 3,927 Откуда: Крипто-Про Сказал(а) «Спасибо»: 20 раз Поблагодарили: 692 раз в 653 постах
|
Здравствуйте. Попробуйте в 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)
| Причина: Не указана |
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 19.02.2018(UTC) Сообщений: 9 Откуда: Москва
|
Автор: afev X509Certificate issuer afev, здравствуйте. Я не понимаю, что такое issuer и откуда мне его взять. Подскажите, пожалуйста.
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 12,721 Сказал «Спасибо»: 500 раз Поблагодарили: 2055 раз в 1595 постах
|
issuer - это сертификата издателя - сертификат УЦ. |
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 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. Это же неправильно?
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close