Статус: Участник
Группы: Участники
Зарегистрирован: 28.06.2018(UTC) Сообщений: 11
Сказал(а) «Спасибо»: 1 раз
|
Собственно, подпись формируется. Без штампа времени подпись проходит проверку на сайте https://www.gosuslugi.ru/pgu/eds/С штампом времени получаем "Внутренняя ошибка". У нас есть подпись, которая проходит проверку на сайте госуслуг, в ans1 формате сравниваю свою подпись с той что проходит и по факту различия только в хэшах и немного структура tSTInfo отличается ![](/forum2/Themes/soclean/icon_file.gif) 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; }
|