Статус: Новичок
Группы: Участники
Зарегистрирован: 29.07.2021(UTC) Сообщений: 2
|
Здравствуйте. Появилась задача добавить время создания подписи. Пример сравнения подписей со смежной системой: [img=https://cloud.mail.ru/public/YemC/twCmbiGYf]Отсутствующее время создания подписи[/img] Подпись отсоединенная в формате pkcs7. Метод, возвращающий бинарник подписи: Код:@Override
public byte[] createCMS(String timeStampServerUrl, byte[] content, X509Certificate x509Certificate, byte[] timestamp, byte[] signature) throws BaseSystemException {
try {
LOGGER.info("INFO START public byte[] createCMS(String timeStampServerUrl, byte[] content, X509Certificate x509Certificate, byte[] timestamp, byte[] signature) throws BaseSystemException Start");
LOGGER.info("timeStampServerUrl: " + timeStampServerUrl);
// выбираем из сертификата информацию для формирования подписи
String AlgInCert = x509Certificate.getPublicKey().getAlgorithm();
if (AlgInCert == JCP.GOST_EL_DEGREE_NAME) {
DIGEST_OID = JCP.GOST_DIGEST_OID;
SIGN_OID = JCP.GOST_EL_KEY_OID;
LOGGER.info("DIGEST_OID = JCP.GOST_DIGEST_OID(1.2.643.2.2.9), SIGN_OID = JCP.GOST_EL_KEY_OID(1.2.643.2.2.19)");
} else if (AlgInCert == JCP.GOST_EL_2012_256_NAME) {
DIGEST_OID = JCP.GOST_DIGEST_2012_256_OID;
SIGN_OID = JCP.GOST_PARAMS_SIG_2012_256_KEY_OID;
LOGGER.info("DIGEST_OID = JCP.GOST_DIGEST_2012_256_OID(1.2.643.7.1.1.2.2), SIGN_OID = JCP.GOST_PARAMS_SIG_2012_256_KEY_OID(1.2.643.7.1.1.1.1)");
} else if (AlgInCert == JCP.GOST_EL_2012_512_NAME) {
DIGEST_OID = JCP.GOST_DIGEST_2012_512_OID;
SIGN_OID = JCP.GOST_PARAMS_SIG_2012_512_KEY_OID;
LOGGER.info("JCP.GOST_DIGEST_2012_512_OID(1.2.643.7.1.1.2.3), SIGN_OID = JCP.GOST_PARAMS_SIG_2012_512_KEY_OID(1.2.643.7.1.1.1.2)");
} else {
LOGGER.info("EXCEPTION INFO in public byte[] createCMS Excetion"
+ "Unknown Algorithm in cert was:" + AlgInCert);
throw new BaseSystemException(Message.BASE_ERROR);
}
final ContentInfo all = new ContentInfo();
all.contentType = new Asn1ObjectIdentifier(new OID(STR_CMS_OID_SIGNED).value);
final SignedData cms = new SignedData();
all.content = cms;
cms.version = new CMSVersion(1);
// digest
cms.digestAlgorithms = new DigestAlgorithmIdentifiers(1);
final DigestAlgorithmIdentifier a = new DigestAlgorithmIdentifier(new OID(DIGEST_OID).value);
a.parameters = new Asn1Null();
cms.digestAlgorithms.elements[0] = a;
Asn1OctetString asn1OctetString = null;
if (content != null)
asn1OctetString = new Asn1OctetString(content);
cms.encapContentInfo = new EncapsulatedContentInfo(
new Asn1ObjectIdentifier(
new OID(STR_CMS_OID_DATA).value),
asn1OctetString);
// certificate
cms.certificates = new CertificateSet(1);
final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate certificate = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate();
Asn1BerDecodeBuffer decodeBuffer = new Asn1BerDecodeBuffer(x509Certificate.getEncoded());
certificate.decode(decodeBuffer);
cms.certificates.elements = new CertificateChoices[1];
cms.certificates.elements[0] = new CertificateChoices();
cms.certificates.elements[0].set_certificate(certificate);
// signer info
cms.signerInfos = new SignerInfos(1);
cms.signerInfos.elements[0] = new SignerInfo();
cms.signerInfos.elements[0].version = new CMSVersion(1);
cms.signerInfos.elements[0].sid = new SignerIdentifier();
//insert timestamp
LOGGER.info("INFO START public byte[] createCMS insert TIMESTAMP Start");
if (timestamp != null && timestamp.length > 0) {
Asn1ObjectIdentifier unsignedObjId = new Asn1ObjectIdentifier(new OID(STR_CMS_OID_UNSIGNED_ATTR).value);
cms.signerInfos.elements[0].unsignedAttrs = new UnsignedAttributes(1);
cms.signerInfos.elements[0].unsignedAttrs.elements[0] = new Attribute(unsignedObjId, new Attribute_values(1));
//ASN1InputStream aIn = new ASN1InputStream(resp);
//aIn.readObject().toASN1Primitive()
ru.CryptoPro.JCP.ASN.PKIXTSP.TimeStampResp tsp = new ru.CryptoPro.JCP.ASN.PKIXTSP.TimeStampResp();
decodeBuffer = new Asn1BerDecodeBuffer(timestamp);
tsp.decode(decodeBuffer);
cms.signerInfos.elements[0].unsignedAttrs.elements[0].values.elements[0] = tsp.timeStampToken;
}
LOGGER.info("Timestamp: " + timestamp.toString());
LOGGER.info("public byte[] createCMS insert TIMESTAMP End");
final byte[] encodedName = (x509Certificate).getIssuerX500Principal().getEncoded();
final Asn1BerDecodeBuffer nameBuf = new Asn1BerDecodeBuffer(encodedName);
final Name name = new Name();
name.decode(nameBuf);
final CertificateSerialNumber num = new CertificateSerialNumber((x509Certificate).getSerialNumber());
cms.signerInfos.elements[0].sid.set_issuerAndSerialNumber(new IssuerAndSerialNumber(name, num));
cms.signerInfos.elements[0].digestAlgorithm = new DigestAlgorithmIdentifier(new OID(DIGEST_OID).value);
cms.signerInfos.elements[0].digestAlgorithm.parameters = new Asn1Null();
cms.signerInfos.elements[0].signatureAlgorithm = new SignatureAlgorithmIdentifier(new OID(SIGN_OID).value);
cms.signerInfos.elements[0].signatureAlgorithm.parameters = new Asn1Null();
cms.signerInfos.elements[0].signature = new SignatureValue(signature);
// encode
LOGGER.info("Start final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer()");
LOGGER.info("Start final Asn1BerEncodeBuffer CMS was:" + cms
+ "/n" + " cms.signerInfos.elements[0].digestAlgorithm.toString()" + cms.signerInfos.elements[0].digestAlgorithm.toString());
LOGGER.info("final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer()");
final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer();
LOGGER.info("all.encode(asnBuf, true)");
all.encode(asnBuf, true);
LOGGER.info(String.format("return asnBuf.getMsgCopy(): %s", asnBuf.getMsgCopy().toString()));
return asnBuf.getMsgCopy();
}
Используется библиотеки bouncycastle 1.49 и от cryptopro jcp 2.0.40035. Дерево зависимостей: [img=https://cloud.mail.ru/public/MCFg/AjL2UVCZP]Дерево зависимостей[/img] Как добавить время создания подписи? Можно дозаполнить параметр какой-нибудь или нужна другая реализация? Позволит ли текущий библиотечный набор реализовать требование?Код легаси с потерянным контролем над кодовой базой. Опыт работы с подписями минимальный. Буду благодарен за советы, полезные ссылки (желательно в разрезе текущей задачи с такими же входными данными)
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 3,926 Откуда: Крипто-Про Сказал(а) «Спасибо»: 20 раз Поблагодарили: 691 раз в 652 постах
|
Здравствуйте. Если имеется в виду подписанный атрибут SigningTime, то в примере CMSSign пакета CMS_samples в samples-sources.jar есть кусок: Код:
//-Time
k += 1;
cms.signerInfos.elements[i + infos.length].signedAttrs.elements[k] =
new Attribute(new OID(CMStools.STR_CMS_OID_SIGN_TYM_ATTR).value,
new Attribute_values(1));
final Time time = new Time();
final Asn1UTCTime UTCTime = new Asn1UTCTime();
//текущая дата с календаря
UTCTime.setTime(Calendar.getInstance());
time.set_utcTime(UTCTime);
cms.signerInfos.elements[i + infos
.length].signedAttrs.elements[k].values.elements[0] =
time.getElement();
|
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 29.07.2021(UTC) Сообщений: 2
|
Благодарю, но проблема не ушла. Использовал частично решение, добавил следующий код: Код:Asn1ObjectIdentifier signedObjId = new Asn1ObjectIdentifier(new OID(STR_CMS_OID_SIGNING_TIME).value);
cms.signerInfos.elements[0].signedAttrs = new SignedAttributes(1);
cms.signerInfos.elements[0].signedAttrs.elements[0] = new Attribute(signedObjId, new Attribute_values(1));
final Time time = new Time();
final Asn1UTCTime UTCTime = new Asn1UTCTime();
//текущая дата с календаря
UTCTime.setTime(Calendar.getInstance());
time.set_utcTime(UTCTime);
cms.signerInfos.elements[0].signedAttrs.elements[0].values.elements[0] = time.getElement();
Теперь код метода стал таким: Код:@Override
public byte[] createCMS(String timeStampServerUrl, byte[] content, X509Certificate x509Certificate, byte[] timestamp, byte[] signature) throws BaseSystemException {
try {
LOGGER.info("INFO START public byte[] createCMS(String timeStampServerUrl, byte[] content, X509Certificate x509Certificate, byte[] timestamp, byte[] signature) throws BaseSystemException Start");
LOGGER.info("timeStampServerUrl: " + timeStampServerUrl);
// выбираем из сертификата информацию для формирования подписи
String AlgInCert = x509Certificate.getPublicKey().getAlgorithm();
if (AlgInCert == JCP.GOST_EL_DEGREE_NAME) {
DIGEST_OID = JCP.GOST_DIGEST_OID;
SIGN_OID = JCP.GOST_EL_KEY_OID;
LOGGER.info("DIGEST_OID = JCP.GOST_DIGEST_OID(1.2.643.2.2.9), SIGN_OID = JCP.GOST_EL_KEY_OID(1.2.643.2.2.19)");
} else if (AlgInCert == JCP.GOST_EL_2012_256_NAME) {
DIGEST_OID = JCP.GOST_DIGEST_2012_256_OID;
SIGN_OID = JCP.GOST_PARAMS_SIG_2012_256_KEY_OID;
LOGGER.info("DIGEST_OID = JCP.GOST_DIGEST_2012_256_OID(1.2.643.7.1.1.2.2), SIGN_OID = JCP.GOST_PARAMS_SIG_2012_256_KEY_OID(1.2.643.7.1.1.1.1)");
} else if (AlgInCert == JCP.GOST_EL_2012_512_NAME) {
DIGEST_OID = JCP.GOST_DIGEST_2012_512_OID;
SIGN_OID = JCP.GOST_PARAMS_SIG_2012_512_KEY_OID;
LOGGER.info("JCP.GOST_DIGEST_2012_512_OID(1.2.643.7.1.1.2.3), SIGN_OID = JCP.GOST_PARAMS_SIG_2012_512_KEY_OID(1.2.643.7.1.1.1.2)");
} else {
LOGGER.info("EXCEPTION INFO in public byte[] createCMS Excetion"
+ "Unknown Algorithm in cert was:" + AlgInCert);
throw new BaseSystemException(Message.BASE_ERROR);
}
final ContentInfo all = new ContentInfo();
all.contentType = new Asn1ObjectIdentifier(new OID(STR_CMS_OID_SIGNED).value);
final SignedData cms = new SignedData();
all.content = cms;
cms.version = new CMSVersion(1);
// digest
cms.digestAlgorithms = new DigestAlgorithmIdentifiers(1);
final DigestAlgorithmIdentifier a = new DigestAlgorithmIdentifier(new OID(DIGEST_OID).value);
a.parameters = new Asn1Null();
cms.digestAlgorithms.elements[0] = a;
Asn1OctetString asn1OctetString = null;
if (content != null)
asn1OctetString = new Asn1OctetString(content);
cms.encapContentInfo = new EncapsulatedContentInfo(
new Asn1ObjectIdentifier(
new OID(STR_CMS_OID_DATA).value),
asn1OctetString);
// certificate
cms.certificates = new CertificateSet(1);
final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate certificate = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate();
Asn1BerDecodeBuffer decodeBuffer = new Asn1BerDecodeBuffer(x509Certificate.getEncoded());
certificate.decode(decodeBuffer);
cms.certificates.elements = new CertificateChoices[1];
cms.certificates.elements[0] = new CertificateChoices();
cms.certificates.elements[0].set_certificate(certificate);
// signer info
cms.signerInfos = new SignerInfos(1);
cms.signerInfos.elements[0] = new SignerInfo();
cms.signerInfos.elements[0].version = new CMSVersion(1);
cms.signerInfos.elements[0].sid = new SignerIdentifier();
//insert timestamp
LOGGER.info("INFO START public byte[] createCMS insert TIMESTAMP Start");
if (timestamp != null && timestamp.length > 0) {
Asn1ObjectIdentifier unsignedObjId = new Asn1ObjectIdentifier(new OID(STR_CMS_OID_UNSIGNED_ATTR).value);
cms.signerInfos.elements[0].unsignedAttrs = new UnsignedAttributes(1);
cms.signerInfos.elements[0].unsignedAttrs.elements[0] = new Attribute(unsignedObjId, new Attribute_values(1));
//ASN1InputStream aIn = new ASN1InputStream(resp);
//aIn.readObject().toASN1Primitive()
ru.CryptoPro.JCP.ASN.PKIXTSP.TimeStampResp tsp = new ru.CryptoPro.JCP.ASN.PKIXTSP.TimeStampResp();
decodeBuffer = new Asn1BerDecodeBuffer(timestamp);
tsp.decode(decodeBuffer);
cms.signerInfos.elements[0].unsignedAttrs.elements[0].values.elements[0] = tsp.timeStampToken;
Asn1ObjectIdentifier signedObjId = new Asn1ObjectIdentifier(new OID(STR_CMS_OID_SIGNING_TIME).value);
cms.signerInfos.elements[0].signedAttrs = new SignedAttributes(1);
cms.signerInfos.elements[0].signedAttrs.elements[0] = new Attribute(signedObjId, new Attribute_values(1));
final Time time = new Time();
final Asn1UTCTime UTCTime = new Asn1UTCTime();
//текущая дата с календаря
UTCTime.setTime(Calendar.getInstance());
time.set_utcTime(UTCTime);
cms.signerInfos.elements[0].signedAttrs.elements[0].values.elements[0] = time.getElement();
}
LOGGER.info("Timestamp: " + timestamp.toString());
LOGGER.info("public byte[] createCMS insert TIMESTAMP End");
final byte[] encodedName = (x509Certificate).getIssuerX500Principal().getEncoded();
final Asn1BerDecodeBuffer nameBuf = new Asn1BerDecodeBuffer(encodedName);
final Name name = new Name();
name.decode(nameBuf);
final CertificateSerialNumber num = new CertificateSerialNumber((x509Certificate).getSerialNumber());
cms.signerInfos.elements[0].sid.set_issuerAndSerialNumber(new IssuerAndSerialNumber(name, num));
cms.signerInfos.elements[0].digestAlgorithm = new DigestAlgorithmIdentifier(new OID(DIGEST_OID).value);
cms.signerInfos.elements[0].digestAlgorithm.parameters = new Asn1Null();
cms.signerInfos.elements[0].signatureAlgorithm = new SignatureAlgorithmIdentifier(new OID(SIGN_OID).value);
cms.signerInfos.elements[0].signatureAlgorithm.parameters = new Asn1Null();
cms.signerInfos.elements[0].signature = new SignatureValue(signature);
// encode
LOGGER.info("Start final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer()");
LOGGER.info("Start final Asn1BerEncodeBuffer CMS was:" + cms
+ "/n" + " cms.signerInfos.elements[0].digestAlgorithm.toString()" + cms.signerInfos.elements[0].digestAlgorithm.toString());
LOGGER.info("final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer()");
final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer();
LOGGER.info("all.encode(asnBuf, true)");
all.encode(asnBuf, true);
LOGGER.info(String.format("return asnBuf.getMsgCopy(): %s", asnBuf.getMsgCopy().toString()));
return asnBuf.getMsgCopy();
} catch (Exception e) {
LOGGER.error("EXCEPTION INFO in public byte[] createCMS Excetion", e);
throw new BaseSystemException(Message.BASE_ERROR);
}
}
Код:private static final String STR_CMS_OID_SIGNING_TIME = "1.2.840.113549.1.9.5";
В подписи появилась необходимая информация, но при этом перестала быть валидной [img=https://cloud.mail.ru/public/Yu1c/SUBVtuEU9]Невалидная подпись[/img] Ответ от стороннего сервиса следующий: "Entity 80feeaa2-71e2-4b0d-8195-e20882f2f64f not found in message 0b097001-1065-423b-8a56-401d163722cd" Как понимаю, добавленный подписываемый атрибут меняет хэш. Попытки добавить неподписываемый атрибут нужного результата не дали. Как это победить?Отредактировано пользователем 2 августа 2021 г. 13:45:55(UTC)
| Причина: Не указана
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 3,926 Откуда: Крипто-Про Сказал(а) «Спасибо»: 20 раз Поблагодарили: 691 раз в 652 постах
|
Время подписи - подписанный атрибут. Подпись должна быть на все подписанные атрибуты, а она, судя по сигнатуре функции, уже посчитана на что-то и просто добавляется в определённое место cms. Посмотрите пример CMSSign в одноимённом файле в пакете CMS_samples. |
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close