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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Александра П  
#1 Оставлено : 21 декабря 2018 г. 9:29:11(UTC)
Александра П

Статус: Участник

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

Сказал(а) «Спасибо»: 1 раз
Добрый день.

Помогите кто-нибудь с штампом времени в отсоединенной подписи. Долго мучаюсь с ним, но при проверке подписи получаю ошибку 0x8009310b Встречено неверное значение тега ASN1.

Как штамп правильно передать в неподписанные атрибуты?

Цитата:

private byte[] signPKCS7(byte[] data, boolean detached, boolean timestamp, PrivateKey[] privateKeys, Certificate[] certs) throws Exception
{
try
{
// Формируем контекст подписи формата PKCS7
final ContentInfo all = new ContentInfo();
all.contentType = new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_SIGNED).value);
final SignedData cms = new SignedData();
all.content = cms;
cms.version = new CMSVersion(1);

// Идентификатор алгоритма хэширования
cms.digestAlgorithms = new DigestAlgorithmIdentifiers(1);
final DigestAlgorithmIdentifier a = new DigestAlgorithmIdentifier(new OID(SignHelper.DIGEST_OID).value);
a.parameters = new Asn1Null();
cms.digestAlgorithms.elements[0] = a;

if (detached) {
cms.encapContentInfo = new EncapsulatedContentInfo(new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_DATA).value), null);
} else {
cms.encapContentInfo = new EncapsulatedContentInfo(new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_DATA).value), new Asn1OctetString(data));
}

// Добавляем сертификат подписи
cms.certificates = new CertificateSet(certs.length);
cms.certificates.elements = new CertificateChoices[certs.length];
for (int i = 0; i < cms.certificates.elements.length; i++) {
final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate ansCertificate = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate();
final Asn1BerDecodeBuffer decodeBuffer = new Asn1BerDecodeBuffer(certs[i].getEncoded());
ansCertificate.decode(decodeBuffer);
cms.certificates.elements[i] = new CertificateChoices();
cms.certificates.elements[i].set_certificate(ansCertificate);
}

// Получаем бинарную подпись длиной 64 байта
final Signature signature = Signature.getInstance(JCP.GOST_EL_SIGN_NAME);
byte[] sign;

// Добавляем информацию о подписанте
cms.signerInfos = new SignerInfos(privateKeys.length);
for (int i = 0; i < cms.signerInfos.elements.length; i++) {
signature.initSign(privateKeys[i]);

cms.signerInfos.elements[i] = new SignerInfo();
cms.signerInfos.elements[i].version = new CMSVersion(1);
cms.signerInfos.elements[i].sid = new SignerIdentifier();

final byte[] encodedName = ((X509Certificate) certs[i]).getIssuerX500Principal().getEncoded();
final Asn1BerDecodeBuffer nameBuf = new Asn1BerDecodeBuffer(encodedName);
final Name name = new Name();
name.decode(nameBuf);

final CertificateSerialNumber num = new CertificateSerialNumber(((X509Certificate) certs[i]).getSerialNumber());
cms.signerInfos.elements[i].sid.set_issuerAndSerialNumber(new IssuerAndSerialNumber(name, num));

cms.signerInfos.elements[i].digestAlgorithm = new DigestAlgorithmIdentifier(new OID(SignHelper.DIGEST_OID).value);
cms.signerInfos.elements[i].digestAlgorithm.parameters = new Asn1Null();

cms.signerInfos.elements[i].signatureAlgorithm = new SignatureAlgorithmIdentifier(new OID(SignHelper.SIGN_OID).value);
cms.signerInfos.elements[i].signatureAlgorithm.parameters = new Asn1Null();

SignedAttributes attrs = new SignedAttributes(3);
cms.signerInfos.elements[i].signedAttrs = attrs;

//-contentType
int k = 0;
cms.signerInfos.elements[i].signedAttrs.elements[k] = new Attribute(new OID(CMStools.STR_CMS_OID_CONT_TYP_ATTR).value, new Attribute_values(1));
final Asn1Type conttype = new Asn1ObjectIdentifier( new OID(CMStools.STR_CMS_OID_DATA).value);
cms.signerInfos.elements[i].signedAttrs.elements[k].values.elements[0] = conttype;

//-Time
k += 1;
final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Time time = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Time();
final Asn1UTCTime UTCTime = new Asn1UTCTime();
//текущая дата с календаря
UTCTime.setTime(Calendar.getInstance());
time.set_utcTime(UTCTime);

cms.signerInfos.elements[i].signedAttrs.elements[k] = new Attribute(new OID(CMStools.STR_CMS_OID_SIGN_TYM_ATTR).value, new Attribute_values(1));
cms.signerInfos.elements[i].signedAttrs.elements[k].values.elements[0] = time.getElement();

//-message digest
k += 1;
cms.signerInfos.elements[i].signedAttrs.elements[k] = new Attribute(new OID(CMStools.STR_CMS_OID_DIGEST_ATTR).value, new Attribute_values(1));

final byte[] messageDigestBlob;
if (cms.encapContentInfo.eContent != null) {
messageDigestBlob = CMStools.digestm(cms.encapContentInfo.eContent.value, CMStools.DIGEST_ALG_NAME, JCP.PROVIDER_NAME);
}
else if (data != null) {
messageDigestBlob = CMStools.digestm(data, CMStools.DIGEST_ALG_NAME, JCP.PROVIDER_NAME);
}
else {
throw new Exception("No content");
}

final Asn1Type messageDigest = new Asn1OctetString(messageDigestBlob);
cms.signerInfos.elements[i].signedAttrs.elements[k].values.elements[0] = messageDigest;

//signature
Asn1DerEncodeBuffer encBufSignedAttr = new Asn1DerEncodeBuffer();
cms.signerInfos.elements[i].signedAttrs.encode(encBufSignedAttr);

final byte[] hsign = encBufSignedAttr.getMsgCopy();
signature.update(hsign);
sign = signature.sign();

cms.signerInfos.elements[i].signature = new SignatureValue(sign);

if (timestamp)
{
cms.signerInfos.elements[i].unsignedAttrs = new UnsignedAttributes(1);
cms.signerInfos.elements[i].unsignedAttrs.elements[0] = new Attribute(new OID(CMStools.STR_CMS_ID_AA_TIMESTAMPTOKEN).value, new Attribute_values(1));
byte[] imprint = CMStools.digestm(sign, CMStools.DIGEST_ALG_NAME, JCP.PROVIDER_NAME); // хэш подписи
TimeStampResponse response = timestampData(imprint);
TimeStampToken timestampToken = response.getTimeStampToken();
Asn1Type value = new Asn1OctetString(timestampToken.getEncoded());
cms.signerInfos.elements[i].unsignedAttrs.elements[0].values.elements[0] = value;

Asn1DerEncodeBuffer encBufUnsignedAttr = new Asn1DerEncodeBuffer();
cms.signerInfos.elements[i].unsignedAttrs.encode(encBufUnsignedAttr);
}
}

// Получаем закодированную подпись
final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer();
all.encode(asnBuf);

return asnBuf.getMsgCopy();
}
catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | CertificateEncodingException | Asn1Exception | IOException ex)
{
return null;
}
}

public TimeStampResponse timestampData(byte[] digest) throws IOException {

String TSA_URL = "http://www.cryptopro.ru/tsp/tsp.srf";

try {
TimeStampRequestGenerator reqgen = new TimeStampRequestGenerator();
TimeStampRequest req = reqgen.generate(TSPAlgorithms.GOST3411, digest);

byte request[] = req.getEncoded();

URL url = new URL(TSA_URL);
HttpURLConnection con = (HttpURLConnection) url.openConnection();

con.setDoOutput(true);
con.setDoInput(true);
con.setConnectTimeout(30000);
con.setRequestMethod("POST");
con.setRequestProperty("Content-type", "application/timestamp-query");
con.setRequestProperty("Content-length", String.valueOf(request.length));
OutputStream out = con.getOutputStream();
try {
out.write(request);
out.flush();
} finally {
out.close();
}

if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("Received HTTP error: " + con.getResponseCode() + " - " + con.getResponseMessage());
}
InputStream in = con.getInputStream();
TimeStampResp resp = TimeStampResp.getInstance(new ASN1InputStream(in).readObject());
TimeStampResponse response = new TimeStampResponse(resp);
response.validate(req);

return response;
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Offline Александра П  
#2 Оставлено : 25 декабря 2018 г. 11:19:38(UTC)
Александра П

Статус: Участник

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

Сказал(а) «Спасибо»: 1 раз
Собственно, подпись формируется. Без штампа времени подпись проходит проверку на сайте https://www.gosuslugi.ru/pgu/eds/
С штампом времени получаем "Внутренняя ошибка".
У нас есть подпись, которая проходит проверку на сайте госуслуг, в ans1 формате сравниваю свою подпись с той что проходит и по факту различия только в хэшах и немного структура tSTInfo отличается Sravnenie podpisejj.png (123kb) загружен 10 раз(а).

Цитата:

private byte[] signPKCS7(byte[] data, boolean detached, boolean timestamp, PrivateKey[] privateKeys, Certificate[] certs, boolean addSignCertV2) throws Exception
{
try
{
// Формируем контекст подписи формата PKCS7
final ContentInfo all = new ContentInfo();
all.contentType = new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_SIGNED).value);
final SignedData cms = new SignedData();
all.content = cms;
cms.version = new CMSVersion(1);

// Идентификатор алгоритма хэширования
cms.digestAlgorithms = new DigestAlgorithmIdentifiers(1);
final DigestAlgorithmIdentifier a = new DigestAlgorithmIdentifier(new OID(SignHelper.DIGEST_OID).value);
a.parameters = new Asn1Null();
cms.digestAlgorithms.elements[0] = a;

if (detached) {
cms.encapContentInfo = new EncapsulatedContentInfo(new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_DATA).value), null);
} else {
cms.encapContentInfo = new EncapsulatedContentInfo(new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_DATA).value), new Asn1OctetString(data));
}

// Добавляем сертификат подписи
cms.certificates = new CertificateSet(certs.length);
cms.certificates.elements = new CertificateChoices[certs.length];
for (int i = 0; i < cms.certificates.elements.length; i++) {
final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate ansCertificate = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate();
final Asn1BerDecodeBuffer decodeBuffer = new Asn1BerDecodeBuffer(certs[i].getEncoded());
ansCertificate.decode(decodeBuffer);
cms.certificates.elements[i] = new CertificateChoices();
cms.certificates.elements[i].set_certificate(ansCertificate);
}

// Получаем бинарную подпись длиной 64 байта
final Signature signature = Signature.getInstance(JCP.GOST_EL_SIGN_NAME);
byte[] sign;

// Добавляем информацию о подписанте
cms.signerInfos = new SignerInfos(privateKeys.length);
for (int i = 0; i < cms.signerInfos.elements.length; i++) {
signature.initSign(privateKeys[i]);

cms.signerInfos.elements[i] = new SignerInfo();
cms.signerInfos.elements[i].version = new CMSVersion(1);
cms.signerInfos.elements[i].sid = new SignerIdentifier();

final byte[] encodedName = ((X509Certificate) certs[i]).getIssuerX500Principal().getEncoded();
final Asn1BerDecodeBuffer nameBuf = new Asn1BerDecodeBuffer(encodedName);
final Name name = new Name();
name.decode(nameBuf);

final CertificateSerialNumber num = new CertificateSerialNumber(((X509Certificate) certs[i]).getSerialNumber());
cms.signerInfos.elements[i].sid.set_issuerAndSerialNumber(new IssuerAndSerialNumber(name, num));

cms.signerInfos.elements[i].digestAlgorithm = new DigestAlgorithmIdentifier(new OID(SignHelper.DIGEST_OID).value);
cms.signerInfos.elements[i].digestAlgorithm.parameters = new Asn1Null();

cms.signerInfos.elements[i].signatureAlgorithm = new SignatureAlgorithmIdentifier(new OID(SignHelper.SIGN_OID).value);
cms.signerInfos.elements[i].signatureAlgorithm.parameters = new Asn1Null();

Integer count = addSignCertV2 ? 4 : 3;
SignedAttributes attrs = new SignedAttributes(count);
cms.signerInfos.elements[i].signedAttrs = attrs;

//-contentType
int k = 0;
cms.signerInfos.elements[i].signedAttrs.elements[k] = new Attribute(new OID(CMStools.STR_CMS_OID_CONT_TYP_ATTR).value, new Attribute_values(1));
final Asn1Type conttype = new Asn1ObjectIdentifier( new OID(CMStools.STR_CMS_OID_DATA).value);
cms.signerInfos.elements[i].signedAttrs.elements[k].values.elements[0] = conttype;

//-Time
k += 1;
final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Time time = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Time();
final Asn1UTCTime UTCTime = new Asn1UTCTime();
//текущая дата с календаря
UTCTime.setTime(Calendar.getInstance());
time.set_utcTime(UTCTime);

cms.signerInfos.elements[i].signedAttrs.elements[k] = new Attribute(new OID(CMStools.STR_CMS_OID_SIGN_TYM_ATTR).value, new Attribute_values(1));
cms.signerInfos.elements[i].signedAttrs.elements[k].values.elements[0] = time.getElement();

//-message digest
k += 1;
cms.signerInfos.elements[i].signedAttrs.elements[k] = new Attribute(new OID(CMStools.STR_CMS_OID_DIGEST_ATTR).value, new Attribute_values(1));

final byte[] messageDigestBlob;
if (cms.encapContentInfo.eContent != null) {
messageDigestBlob = CMStools.digestm(cms.encapContentInfo.eContent.value, CMStools.DIGEST_ALG_NAME, JCP.PROVIDER_NAME);
}
else if (data != null) {
messageDigestBlob = CMStools.digestm(data, CMStools.DIGEST_ALG_NAME, JCP.PROVIDER_NAME);
}
else {
throw new Exception("No content");
}

final Asn1Type messageDigest = new Asn1OctetString(messageDigestBlob);
cms.signerInfos.elements[i].signedAttrs.elements[k].values.elements[0] = messageDigest;

// Добавление signingCertificateV2 в подписанные аттрибуты, чтобы подпись
// стала похожа на CAdES-BES.
if (addSignCertV2) {

// Собственно, аттрибут с OID'ом id_aa_signingCertificateV2.
k += 1;
cms.signerInfos.elements[i].signedAttrs.elements[k] = new Attribute(new OID(ALL_PKIX1Explicit88Values.id_aa_signingCertificateV2).value, new Attribute_values(1));

// Идентификатор алгоритма хеширования, который использовался для
// хеширования контекста сертификата ключа подписи.
final DigestAlgorithmIdentifier digestAlgorithmIdentifier = new DigestAlgorithmIdentifier(new OID(SignHelper.DIGEST_OID).value);

// Хеш сертификата ключа подписи.
final CertHash certHash = new CertHash(CMStools.digestm(((Certificate)secureData[0]).getEncoded(), CMStools.DIGEST_ALG_NAME, JCP.PROVIDER_NAME));

// Issuer name из сертификата ключа подписи.
GeneralName generalName = new GeneralName();
generalName.set_directoryName(name);

GeneralNames generalNames = new GeneralNames();
generalNames.elements = new GeneralName[1];
generalNames.elements[0] = generalName;

// Комбинируем издателя и серийный номер.
IssuerSerial issuerSerial = new IssuerSerial(generalNames, num);

ESSCertIDv2 essCertIDv2 = new ESSCertIDv2(digestAlgorithmIdentifier, certHash, issuerSerial);

_SeqOfESSCertIDv2 essCertIDv2s = new _SeqOfESSCertIDv2(1);
essCertIDv2s.elements = new ESSCertIDv2[1];
essCertIDv2s.elements[0] = essCertIDv2;

// Добавляем сам аттрибут.
SigningCertificateV2 signingCertificateV2 = new SigningCertificateV2(essCertIDv2s);
cms.signerInfos.elements[i].signedAttrs.elements[k].values.elements[0] = signingCertificateV2;
}

//signature
Asn1DerEncodeBuffer encBufSignedAttr = new Asn1DerEncodeBuffer();
cms.signerInfos.elements[i].signedAttrs.encode(encBufSignedAttr);

final byte[] hsign = encBufSignedAttr.getMsgCopy();
signature.update(hsign);
sign = signature.sign();

cms.signerInfos.elements[i].signature = new SignatureValue(sign);

if (timestamp)
{
cms.signerInfos.elements[i].unsignedAttrs = new UnsignedAttributes(1);
cms.signerInfos.elements[i].unsignedAttrs.elements[0] = new Attribute(new OID(CMStools.STR_CMS_ID_AA_TIMESTAMPTOKEN).value, new Attribute_values(1));
// JCP.GOST_DIGEST_2012_256_NAME
byte[] imprint = CMStools.digestm(sign, JCP.GOST_DIGEST_NAME, JCP.PROVIDER_NAME); // хэш подписи
TimeStampResponse response = timestampData(imprint);
TimeStampToken timestampToken = response.getTimeStampToken();
Asn1Type value = new Asn1OctetString(timestampToken.getEncoded());
cms.signerInfos.elements[i].unsignedAttrs.elements[0].values.elements[0] = value;

Asn1DerEncodeBuffer encBufUnsignedAttr = new Asn1DerEncodeBuffer();
cms.signerInfos.elements[i].unsignedAttrs.encode(encBufUnsignedAttr);
}
}

// Получаем закодированную подпись
final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer();
all.encode(asnBuf);

return asnBuf.getMsgCopy();
}
catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | CertificateEncodingException | Asn1Exception | IOException ex)
{
return null;
}
}

public TimeStampResponse timestampData(byte[] digest) throws IOException {

String TSA_URL = "http://www.cryptopro.ru/tsp/tsp.srf";

try {
TimeStampRequestGenerator reqgen = new TimeStampRequestGenerator();
reqgen.setCertReq(true);
TimeStampRequest req = reqgen.generate(TSPAlgorithms.GOST3411, digest, BigInteger.valueOf(System.currentTimeMillis()));

byte request[] = req.getEncoded();

URL url = new URL(TSA_URL);
HttpURLConnection con = (HttpURLConnection) url.openConnection();

con.setDoOutput(true);
con.setDoInput(true);
con.setConnectTimeout(30000);
con.setRequestMethod("POST");
con.setRequestProperty("Content-type", "application/timestamp-query");
con.setRequestProperty("Content-length", String.valueOf(request.length));
OutputStream out = con.getOutputStream();
try {
out.write(request);
out.flush();
} finally {
out.close();
}

if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("Received HTTP error: " + con.getResponseCode() + " - " + con.getResponseMessage());
}
InputStream in = con.getInputStream();
TimeStampResp resp = TimeStampResp.getInstance(new ASN1InputStream(in).readObject());
TimeStampResponse response = new TimeStampResponse(resp);
response.validate(req);

return response;
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest (2)
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.