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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline VladOG  
#1 Оставлено : 1 ноября 2022 г. 16:26:55(UTC)
VladOG

Статус: Новичок

Группы: Участники
Зарегистрирован: 01.11.2022(UTC)
Сообщений: 1
Российская Федерация
Откуда: Rostov-on-Don

При создании подписи на основе модифицированного примера из
jcp-2.0.40035\Doc\sample-source\CMS_samples\DetachedSignatureFileExample.java
и
jcp-2.0.40035\Doc\sample-source\CMS_samples\CMS.java
и проверке ее внутренним методом на валидность получаем валидную подпись.
А вот при проверке на сайте https://crypto.kontur.ru/verify#result
получаем сообщение об ошибке : Подпись не подтверждена. Файл был модифицирован или подпись не соответствует файлу.
Помогите пожалуйста разобраться

Код:

package utils.CMS;
.....
public class DetachedSignatureFileExample {

    public static final String fileName = "C:\\eClinic\\test.pdf";
    public static final String alias = "?????????????";
    public static final char[] password = "********".toCharArray();

    public static void main(String[] args) throws Exception {

        // Грузим хранилище.
        KeyStore keyStore = KeyStore.getInstance(JCP.HD_STORE_NAME);
        keyStore.load(null, null);

        // Получаем ключ и сертификат.
        PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password);
        X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias);

        String algorithm = JCP.GOST_SIGN_2012_256_NAME;
        // Создаем подпись, при этом сначала получаем хеш с файла.

	byte[] data = VUtl.readFile( fileName);
        Signature signature = Signature.getInstance(algorithm );
        signature.initSign(privateKey);
	signature.update( data);
       

        // Создаем подпись.
        byte[] cms = CMS.createCMS(data, signature.sign(), certificate, true);
        VUtl.writeToFile( cms, fileName+".sig");
        
        // Проверяем подпись, снова сначала получаем хеш с файла.
        signature = Signature.getInstance( algorithm );
        signature.initVerify(certificate.getPublicKey());
  	signature.update( data);

        verify(cms, certificate, signature);

    }


    public static void verify(byte[] buffer, X509Certificate cert, Signature signature)
            throws Exception {

        int i;
        final Asn1BerDecodeBuffer asnBuf = new Asn1BerDecodeBuffer(buffer);
        final ContentInfo all = new ContentInfo();

        all.decode(asnBuf);

        if (!new OID(CMStools.STR_CMS_OID_SIGNED).eq(all.contentType.value)) {
            throw new Exception("Not supported");
        }

        final SignedData cms = (SignedData) all.content;

        if (cms.version.value != 1) {
            throw new Exception("Incorrect version");
        }

        if (!new OID(CMStools.STR_CMS_OID_DATA).eq(cms.encapContentInfo.eContentType.value)) {
            throw new Exception("Nested not supported");
        }

        OID digestOid = null;

        DigestAlgorithmIdentifier a = new DigestAlgorithmIdentifier(new OID(CMStools.DIGEST_OID_2012_256).value);

        for (i = 0; i < cms.digestAlgorithms.elements.length; i++) {
            if (cms.digestAlgorithms.elements[i].algorithm.equals(a.algorithm)) {
                digestOid =
                        new OID(cms.digestAlgorithms.elements[i].algorithm.value);
                break;
            }
        }

        if (digestOid == null) {
            throw new Exception("Unknown digest");
        }

        int pos = -1;

        for (i = 0; i < cms.certificates.elements.length; i++) {

            final Asn1BerEncodeBuffer encBuf = new Asn1BerEncodeBuffer();
            cms.certificates.elements[i].encode(encBuf);

            final byte[] in = encBuf.getMsgCopy();

            X509Certificate tmp = (X509Certificate) CertificateFactory.getInstance("X.509")
                .generateCertificate(new ByteArrayInputStream(in));

            System.out.println(tmp.getSubjectDN());
            System.out.println(cert.getSubjectDN());

            if (Arrays.equals(in, cert.getEncoded())) {
                pos = i;
                break;
            }
        }

        if (pos == -1) {
            throw new Exception("Not signed on certificate.");
        }

        final SignerInfo info = cms.signerInfos.elements[pos];

        if (info.version.value != 1) {
            throw new Exception("Incorrect version");
        }

        if (!digestOid.equals(new OID(info.digestAlgorithm.algorithm.value))) {
            throw new Exception("Not signed on certificate.");
        }

        final byte[] sign = info.signature.value;

        // check
        final boolean checkResult = signature.verify(sign);

        if (checkResult) {
            if (CMStools.logger != null) {
                CMStools.logger.info("Valid signature");
            }
        }
        else {
            throw new Exception("Invalid signature.");
        }
    }

/////////////////////////////////////////////////////////////////////////////////////////

package utils.CMS;
.............................
public class CMS {
.............................
public static byte[] createCMS(
		byte[] data
	 , byte[] sign
	 , Certificate cert
	 , boolean detached
) throws Exception {
    return createCMSEx( 
   		 data
   	  , sign
   	  , cert
   	  , detached
   	  , CMStools.DIGEST_OID_2012_256
   	  , CMStools.SIGN_OID_2012_256
   	  , CMStools.DIGEST_ALG_NAME_2012_256
   	  , JCP.PROVIDER_NAME 
   );
}

/**
 * createCMS
 *
 * @param data : bytes[] of file for signed
 * @param sign sign
 * @param cert cert
 * @param detached detached signature
 * @param digestOid digest algorithm OID (to append to CMS)
 * @param signOid signature algorithm OID (to append to CMS)
 * @return byte[]
 * @throws Exception e
 * @since 2.0
 */
public static byte[] createCMSEx(
		byte[] data
	 , byte[] sign
	 , Certificate cert
	 , boolean detached
	 , String digestOid
	 , String signOid
	 , String digestAlg
	 , String providerName 
) throws Exception {
	
	 //create hashCMS // Формируем контекст подписи формата 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);

    // digest // Идентификатор алгоритма хеширования.

    cms.digestAlgorithms = new DigestAlgorithmIdentifiers(1);
    final DigestAlgorithmIdentifier a = new DigestAlgorithmIdentifier( new OID(digestOid).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));
    } 

    // certificate // Добавляем сертификат подписи.
    cms.certificates = new CertificateSet(1);
    final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate certificate = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate();
    final Asn1BerDecodeBuffer decodeBuffer =  new Asn1BerDecodeBuffer(cert.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();

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

    final CertificateSerialNumber num = new CertificateSerialNumber(((X509Certificate) cert).getSerialNumber());
    cms.signerInfos.elements[0].sid.set_issuerAndSerialNumber(new IssuerAndSerialNumber(name, num));
    cms.signerInfos.elements[0].digestAlgorithm = new DigestAlgorithmIdentifier(new OID(digestOid).value);
    cms.signerInfos.elements[0].digestAlgorithm.parameters = new Asn1Null();
    cms.signerInfos.elements[0].signatureAlgorithm = new SignatureAlgorithmIdentifier(new OID(signOid).value);
    cms.signerInfos.elements[0].signatureAlgorithm.parameters = new Asn1Null();
    cms.signerInfos.elements[0].signature = new SignatureValue(sign);
////+++++++++++++++++
    //signedAttributes
    final int kmax = 4;
    cms.signerInfos.elements[0].signedAttrs = new SignedAttributes(kmax);

    //-contentType
    int k = 0;
    cms.signerInfos.elements[0].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[0].signedAttrs.elements[k].values.elements[0] = conttype;
    
    //-Time
    k += 1;
    cms.signerInfos.elements[0].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[0].signedAttrs.elements[k].values.elements[0] = time.getElement();
    
    //-message digest !!! ?????????????????
    k += 1;
    cms.signerInfos.elements[0].signedAttrs.elements[k] = new Attribute(
   		  new OID(CMStools.STR_CMS_OID_DIGEST_ATTR).value
   		 		,new Attribute_values(1));

    final byte[] messageDigestBlob;
    if (detached) {
   	 messageDigestBlob = CMStools.digestm(data, digestAlg, providerName);
    } // if
    else {
   	 messageDigestBlob = CMStools.digestm(cms.encapContentInfo.eContent.value,digestAlg, providerName);
    } // else	
    final Asn1Type messageDigest = new Asn1OctetString( messageDigestBlob);
    cms.signerInfos.elements[0].signedAttrs.elements[k].values.elements[0] = messageDigest;
////*******
    // Добавление signingCertificateV2 в подписанные аттрибуты, чтобы подпись
    // стала похожа на CAdES-BES.

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

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

        // Хеш сертификата ключа подписи.
        final CertHash certHash = new CertHash(
            CMStools.digestm(cert.getEncoded(), digestAlg, providerName));

        // 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[0].signedAttrs.elements[k].values.elements[0] = signingCertificateV2;

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

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