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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline pls  
#1 Оставлено : 7 ноября 2011 г. 18:38:38(UTC)
pls

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

Группы: Участники
Зарегистрирован: 04.10.2011(UTC)
Сообщений: 74
Откуда: Moscow

Сказал(а) «Спасибо»: 1 раз
Поблагодарили: 1 раз в 1 постах
КриптоАРМ при проверке CAdES-X Long Type 1 подписи падает с ошибкой "Усовершенствованная подпись не содержит штампа времени на доказательства подписи или он не действителен" думаю и плагин к браузеру падает по этой же причине. В сертификатах проблем нет - все они валидны и установлены. Грешу на неправильное формирование атрибута CAdES-C-time-stamp, возможно я неправильно понял RFC.
Делаю так:
объекты SignatureValue, Attribute(штампа времени подписи, с ОИДом и единственной вложенной структурой TimeStampToken), Attribute(complete-certificate-references с ОИДом и структурой CompleteCertificateRefs), Attribute(complete-revocation-references с ОИДом и структурой CompleteRevocationRefs) декодирую в der (каждую из 4 структур в отдельности), склеиваю 4 массива полученных байтов, беру хэш от полученного массива - этот хеш и идет в структуру messageImprint запроса TimeStampReq. Подскажите пожалуйста, что я делаю не так

Для большей наглядности:
Код:
private UnsignedAttributes composeUnsignedAttrs(X509Certificate userCert, X509Certificate[] caCertChain, SignatureValue signature, TSASetting tsaSetting, String ocspUrl) throws Exception {
		//signature-time-stamp
		Attribute tsAttr = new Attribute(new OID(STR_TS_OID_ATTR).value, new Attribute_values(1));
		tsAttr.values.elements[0] = getTimeStampToken(tsaSetting, signature.value);

		//todo think about array od bocspr
		BasicOCSPResponse[] ocspResponses = checkCertStatus(ocspUrl, userCert, caCertChain[0]);
		X509Certificate[] ocspCerts = getOCSPCerts(ocspResponses);

		//complete-certificate-references
		Attribute ccrAttr = new Attribute(new OID(STR_COMPLETE_CERTIFICATE_REFS_OID_ATTR).value, new Attribute_values(1));
		ccrAttr.values.elements[0] = getCompleteCertRefs(caCertChain, ocspCerts);

		//complete-revocation-references
		Attribute crrAttr = new Attribute(new OID(STR_COMPLETE_REVOCATION_REFERENCES).value, new Attribute_values(1));
		crrAttr.values.elements[0] = getCompleteRevRefs(ocspResponses);

		//certificate-values
		Attribute certValAttr = new Attribute(new OID(STR_CERTIFICATE_VALS_OID_ATTR).value, new Attribute_values(1));
		certValAttr.values.elements[0] = getCertificateValues(userCert, caCertChain, ocspCerts);

		//revocation-values
		Attribute revValAttr = new Attribute(new OID(STR_REVOCATION_VALS_OID_ATTR).value, new Attribute_values(1));
		revValAttr.values.elements[0] = getRevocationValues(ocspResponses);

		//CAdES-C-time-stamp
		Attribute cadesCTSAttr = new Attribute(new OID(STR_CADES_C_TIME_STAMP_OID_ATTR).value, new Attribute_values(1));
		cadesCTSAttr.values.elements[0] = getCAdESCTimeStamp(tsaSetting, signature, tsAttr, ccrAttr, crrAttr);
		return new UnsignedAttributes(new Attribute[] {crrAttr, ccrAttr, revValAttr, cadesCTSAttr, certValAttr, tsAttr});
}

private TimeStampToken getCAdESCTimeStamp(TSASetting setting, SignatureValue signature, Asn1Type tsAttr, Asn1Type ccrAttr, Asn1Type crrAttr) throws Exception {
		byte[] data = composeCAdESCTimeStampData(signature, tsAttr, ccrAttr, crrAttr);
		TimeStampReq request = createTimeStampRequest(setting, data, true);
		TimeStampResp response = callTSA(setting.url, toDER(request));

		if (response.status.status.value != 0 &&
			response.status.status.value != 1) {
			throw new RuntimeException("illegal tsp status:" + response.status.status.value);
		}
		return response.timeStampToken;
}

private TimeStampReq createTimeStampRequest(TSASetting tsaSetting, byte[] data, boolean includeCert) throws Exception {
		TimeStampReq r = new TimeStampReq();
		r.version = new TimeStampReq_version(BigInteger.ONE);
		r.messageImprint = new MessageImprint(getHashAlgId(), new Asn1OctetString(digestm(data, JCP.GOST_DIGEST_NAME)));
		r.reqPolicy = new TSAPolicyId(new OID(tsaSetting.policy).value);
		r.nonce = new Asn1BigInteger(BigInteger.valueOf(SecureRandom.getInstance("SHA1PRNG").nextLong()));
		r.certReq = new Asn1Boolean(includeCert);
		return r;
}

public static byte[] composeCAdESCTimeStampData(SignatureValue sigVal, Asn1Type tsAttr, Asn1Type ccrAttr, Asn1Type crrAttr) throws Asn1Exception {
		return arrayConcat(toDER(sigVal), toDER(tsAttr), toDER(ccrAttr), toDER(crrAttr));
}

private static byte[] arrayConcat(byte[]... arrays) {
//склеивает N массивов в единый массив, с сохранение порядка переданных массисов
}

private static byte[] toDER(Asn1Type entity) throws Asn1Exception {
		Asn1DerEncodeBuffer encodedData = new Asn1DerEncodeBuffer();
		entity.encode(encodedData);
		return encodedData.getMsgCopy();
}

private TimeStampResp callTSA(String url, byte[] tspRequest) throws IOException, Asn1Exception {
//вызывает удаленный tsa, передает даннык tspRequest, возвращает TimeStampResp.
}
Offline Новожилова Елена  
#2 Оставлено : 7 ноября 2011 г. 19:11:07(UTC)
Новожилова Елена

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

Группы: Администраторы, Участники
Зарегистрирован: 10.12.2008(UTC)
Сообщений: 924
Женщина
Откуда: Крипто-Про

Поблагодарили: 99 раз в 95 постах
В RFC 5126 раздел 6.3.5 (CAdES-C-time-stamp Attribute Definition) замечание 2:

NOTE 2: Each attribute is included in the hash with the attrType
and attrValues (including type and length) but without the type
and length of the outer SEQUENCE
.
Offline pls  
#3 Оставлено : 7 ноября 2011 г. 20:20:54(UTC)
pls

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

Группы: Участники
Зарегистрирован: 04.10.2011(UTC)
Сообщений: 74
Откуда: Moscow

Сказал(а) «Спасибо»: 1 раз
Поблагодарили: 1 раз в 1 постах
Спасибо, попробовал так:
Код:

private UnsignedAttributes composeUnsignedAttrs(X509Certificate userCert, X509Certificate[] caCertChain, SignatureValue signature, TSASetting tsaSetting, String ocspUrl) throws Exception {
		//signature-time-stamp
		Asn1ObjectIdentifier tsOid = new Asn1ObjectIdentifier(new OID(STR_TS_OID_ATTR).value);
		Attribute_values tsValues = new Attribute_values(new TimeStampToken[]{getTimeStampToken(tsaSetting, signature.value)});
		Attribute tsAttr = new Attribute(tsOid, tsValues);

		//todo think about array od bocspr
		BasicOCSPResponse[] ocspResponses = checkCertStatus(ocspUrl, userCert, caCertChain[0]);
		X509Certificate[] ocspCerts = getOCSPCerts(ocspResponses);

		//complete-certificate-references
		Asn1ObjectIdentifier ccrOid = new Asn1ObjectIdentifier(new OID(STR_COMPLETE_CERTIFICATE_REFS_OID_ATTR).value);
		Attribute_values ccrValues = new Attribute_values(new CompleteCertificateRefs[]{getCompleteCertRefs(caCertChain, ocspCerts)});
		Attribute ccrAttr = new Attribute(ccrOid, ccrValues);

		//complete-revocation-references
		Asn1ObjectIdentifier crrOid = new Asn1ObjectIdentifier(new OID(STR_COMPLETE_REVOCATION_REFERENCES).value);
		Attribute_values crrValues = new Attribute_values(new CompleteRevocationRefs[]{getCompleteRevRefs(ocspResponses)});
		Attribute crrAttr = new Attribute(crrOid, crrValues);

		//certificate-values
		Attribute certValAttr = new Attribute(new OID(STR_CERTIFICATE_VALS_OID_ATTR).value, new Attribute_values(1));
		certValAttr.values.elements[0] = getCertificateValues(userCert, caCertChain, ocspCerts);

		//revocation-values
		Attribute revValAttr = new Attribute(new OID(STR_REVOCATION_VALS_OID_ATTR).value, new Attribute_values(1));
		revValAttr.values.elements[0] = getRevocationValues(ocspResponses);

		//CAdES-C-time-stamp
		Attribute cadesCTSAttr = new Attribute(new OID(STR_CADES_C_TIME_STAMP_OID_ATTR).value, new Attribute_values(1));
		cadesCTSAttr.values.elements[0] = getCAdESCTimeStamp(tsaSetting, signature,  tsOid, tsValues, ccrOid, ccrValues, crrOid, crrValues);
		return new UnsignedAttributes(new Attribute[] {crrAttr, ccrAttr, revValAttr, cadesCTSAttr, certValAttr, tsAttr});
}


и так
Код:

private UnsignedAttributes composeUnsignedAttrs(X509Certificate userCert, X509Certificate[] caCertChain, SignatureValue signature, TSASetting tsaSetting, String ocspUrl) throws Exception {
		//signature-time-stamp
		Asn1ObjectIdentifier tsOid = new Asn1ObjectIdentifier(new OID(STR_TS_OID_ATTR).value);
		Attribute_values tsValues = new Attribute_values(new TimeStampToken[]{getTimeStampToken(tsaSetting, signature.value)});
		AttributeTypeAndValue tsTV = new AttributeTypeAndValue(tsOid, new Asn1OpenType(toDER(tsValues)));
		Attribute tsAttr = new Attribute(tsOid, tsValues);

		//todo think about array od bocspr
		BasicOCSPResponse[] ocspResponses = checkCertStatus(ocspUrl, userCert, caCertChain[0]);
		X509Certificate[] ocspCerts = getOCSPCerts(ocspResponses);

		//complete-certificate-references
		Asn1ObjectIdentifier ccrOid = new Asn1ObjectIdentifier(new OID(STR_COMPLETE_CERTIFICATE_REFS_OID_ATTR).value);
		Attribute_values ccrValues = new Attribute_values(new CompleteCertificateRefs[]{getCompleteCertRefs(caCertChain, ocspCerts)});
		AttributeTypeAndValue ccrTV = new AttributeTypeAndValue(ccrOid, new Asn1OpenType(toDER(ccrValues)));
		Attribute ccrAttr = new Attribute(ccrOid, ccrValues);

		//complete-revocation-references
		Asn1ObjectIdentifier crrOid = new Asn1ObjectIdentifier(new OID(STR_COMPLETE_REVOCATION_REFERENCES).value);
		Attribute_values crrValues = new Attribute_values(new CompleteRevocationRefs[]{getCompleteRevRefs(ocspResponses)});
		AttributeTypeAndValue crrTV = new AttributeTypeAndValue(crrOid, new Asn1OpenType(toDER(crrValues)));
		Attribute crrAttr = new Attribute(crrOid, crrValues);

		//certificate-values
		Attribute certValAttr = new Attribute(new OID(STR_CERTIFICATE_VALS_OID_ATTR).value, new Attribute_values(1));
		certValAttr.values.elements[0] = getCertificateValues(userCert, caCertChain, ocspCerts);

		//revocation-values
		Attribute revValAttr = new Attribute(new OID(STR_REVOCATION_VALS_OID_ATTR).value, new Attribute_values(1));
		revValAttr.values.elements[0] = getRevocationValues(ocspResponses);

		//CAdES-C-time-stamp
		Attribute cadesCTSAttr = new Attribute(new OID(STR_CADES_C_TIME_STAMP_OID_ATTR).value, new Attribute_values(1));
		cadesCTSAttr.values.elements[0] = getCAdESCTimeStamp(tsaSetting, signature, tsTV, ccrTV, crrTV);
		return new UnsignedAttributes(new Attribute[] {crrAttr, ccrAttr, revValAttr, cadesCTSAttr, certValAttr, tsAttr});
}

функция getCAdESCTimeStamp работает аналогично предыдущему посту только с другими кол-вом параметров.
падает с той же ошибкой.
Offline Новожилова Елена  
#4 Оставлено : 7 ноября 2011 г. 20:40:45(UTC)
Новожилова Елена

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

Группы: Администраторы, Участники
Зарегистрирован: 10.12.2008(UTC)
Сообщений: 924
Женщина
Откуда: Крипто-Про

Поблагодарили: 99 раз в 95 постах
Атрибуты передаются для хэширования закодированными в DER, но без указания длины и внешнего тега SEQUENCE.
Offline pls  
#5 Оставлено : 7 ноября 2011 г. 23:03:45(UTC)
pls

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

Группы: Участники
Зарегистрирован: 04.10.2011(UTC)
Сообщений: 74
Откуда: Moscow

Сказал(а) «Спасибо»: 1 раз
Поблагодарили: 1 раз в 1 постах
Елена, не понятно относительно чего "внешний".
Если относительно сущности атрибута:
Attribute ::= SEQUENCE {
attrType OBJECT IDENTIFIER,
attrValues SET OF AttributeValue
}

то Attribute внешний, а attrType и attrValues закодированные в der нужно включить в хеш - я делаю именно так.
Иначе только разворачивать иерархию до примитивов.

Будет гораздо понятней, если вы приведете пример кода одного из атрибутов который останется только закодировать в der и склеить с der-кодироваными остальными атрибутами.
Offline pls  
#6 Оставлено : 7 ноября 2011 г. 23:36:49(UTC)
pls

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

Группы: Участники
Зарегистрирован: 04.10.2011(UTC)
Сообщений: 74
Откуда: Moscow

Сказал(а) «Спасибо»: 1 раз
Поблагодарили: 1 раз в 1 постах
похоже проблема была в том что бралась toDER(signature), где signature = SignatureValue, нужно было просто value вытаскивать и склеивать с der-кодированными атрибутами.
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest (2)
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.