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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline U3962  
#1 Оставлено : 11 марта 2025 г. 7:56:32(UTC)
U3962

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

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

Сказал(а) «Спасибо»: 10 раз
Поблагодарили: 3 раз в 2 постах
Добрый день.
Пытаемся взаимодействовать с ГИС ЖКХ.
Там примерно как в СМЭВ 3 - SOAP и подписанная XML.
Требования ЖКХ к подписи такие:
trebovanija_k_podpisi.zip (20kb) загружен 2 раз(а).


Подписываем примерно как СМЭВ:
Код:
package TESTXMLSIGN;
	import java.io.ByteArrayInputStream;
	import java.io.ByteArrayOutputStream;
	import java.io.FileOutputStream;
	import java.nio.file.Files;
	import java.nio.file.Paths;
	import java.security.KeyStore;
	import java.security.PrivateKey;
	import java.security.cert.X509Certificate;
	
	
	import javax.xml.parsers.DocumentBuilder;
	import javax.xml.parsers.DocumentBuilderFactory;
	import javax.xml.transform.OutputKeys;
	import javax.xml.transform.Transformer;
	import javax.xml.transform.TransformerFactory;
	import javax.xml.transform.dom.DOMSource;
	import javax.xml.transform.stream.StreamResult;
	
	import org.apache.xml.security.signature.XMLSignature;
	import org.apache.xml.security.transforms.Transform;
	import org.apache.xml.security.transforms.Transforms;
	import org.w3c.dom.Document;
	import org.w3c.dom.Element;
	import org.w3c.dom.NodeList;



public class Main {

	private static final String CANONICALIZATION_METHOD = "http://www.w3.org/2001/10/xml-exc-c14n#";
	private static final String SIG_ID = "sigID";
	private static final String COULD_NOT_FIND_XML_ELEMENT_NAME = "ERROR! Could not find xmlElementName = ";
	private static final String GRID = "#";

	
	private static final String signMethod = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256";
	private static final String digestMethod = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256";

	private static final String canonicalizationMethod = CANONICALIZATION_METHOD;

	
	
	public static ByteArrayOutputStream MakeXMLSign(byte[] data,String xmlElementName,String xmlElementID,X509Certificate x509Cert,PrivateKey privateKey) throws Exception 
	{
		ByteArrayOutputStream bais;

		// инициализация объекта чтения XML-документа
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		// установка флага, определяющего игнорирование пробелов в
		// содержимом элементов при обработке XML-документа
		dbf.setIgnoringElementContentWhitespace(true);
		// установка флага, определяющего преобразование узлов CDATA в
		// текстовые узлы при обработке XML-документа
		dbf.setCoalescing(true);
		// установка флага, определяющего поддержку пространств имен при
		// обработке XML-документа
		dbf.setNamespaceAware(true);

		DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
		Document doc = documentBuilder.parse(new ByteArrayInputStream(data));
	            
        //signature ID   
		String sigId = SIG_ID;
    
		// инициализация объекта формирования ЭЦП в соответствии с алгоритмом ГОСТ Р 34.10-2001
		XMLSignature sig = new XMLSignature(doc, "", signMethod, canonicalizationMethod);

		// определение идентификатора первого узла подписи
		sig.setId(sigId);
    
        // получение корневого узла XML-документа
        Element anElement = null;
   
        NodeList nodeList = doc.getElementsByTagName(xmlElementName);// xmlElementName=ns2:CallerInformationSystemSignature   OR   xmlElementName=ns:PersonalSignature
        //Get first node - place to sign
        anElement = (Element) nodeList.item(0);

        // добавление в корневой узел XML-документа узла подписи
        if (anElement != null) {
            anElement.appendChild(sig.getElement());
        } else {
            throw new Exception(COULD_NOT_FIND_XML_ELEMENT_NAME + xmlElementName);
        }

        // создание узла преобразований <ds:Transforms> обрабатываемого XML-документа
        Transforms transforms = new Transforms(doc);
        
        // добавление в узел преобразований правил работы с документом
        transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
        transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
        
        //For SMEV3
        //transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
        //transforms.addTransform(SmevTransformSpi.ALGORITHM_URN);
        //For SMEV3	
        
        // добавление в узел подписи ссылок (узла <ds:Reference>),
        // определяющих правила работы с
        // XML-документом (обрабатывается текущий документ с заданными в
        // узле <ds:Transforms> правилами
        // и заданным алгоритмом хеширования)
        sig.addDocument(xmlElementID == null ? "" : GRID + xmlElementID, transforms, digestMethod);

		// создание внутри узла подписи узла <ds:KeyInfo> информации об открытом ключе на основе сертификата
        sig.addKeyInfo(x509Cert);
        
        // создание подписи XML-документа
        sig.sign(privateKey);
    
	    // определение потока, в который осуществляется запись подписанного XML-документа
	    bais = new ByteArrayOutputStream();
    
	    // инициализация объекта копирования содержимого XML-документа в поток
	    TransformerFactory tf = TransformerFactory.newInstance();
    
	    // создание объекта копирования содержимого XML-документа в поток
	    Transformer trans = tf.newTransformer();

	    trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

	    // копирование содержимого XML-документа в поток
	    trans.transform(new DOMSource(doc), new StreamResult(bais));
	    bais.close();
		return bais;
	
	}

    

	
	public static void main(String[] args) throws Exception {
		
	
		// XML сообщение в виде массива байтов
		byte[] data = Files.readAllBytes(Paths.get("test.xml"));
	    //ignoreLineBreaks
		System.setProperty("org.apache.xml.security.ignoreLineBreaks", "true");
		//init xmldsig
		ru.CryptoPro.JCPxml.xmldsig.JCPXMLDSigInit.init();
		//register SMEV3 transformation
        Transform.register(SmevTransformSpi.ALGORITHM_URN, SmevTransformSpi.class.getName());

        //keystore	
        String cer_story = "HDImageStore";
        //container
		String cer_alias = "gis-smev-cert";
		//password
		String cer_pass_str = "xxxx";

		char[] cer_pass = cer_pass_str.toCharArray();
		//load key store
		KeyStore keyStore = KeyStore.getInstance( cer_story );
		keyStore.load( null, null );
		PrivateKey privateKey = (PrivateKey) keyStore.getKey( cer_alias, cer_pass );	
		//cert
		X509Certificate x509Cert = (X509Certificate) keyStore.getCertificate( cer_alias );

		String xmlElementName = "exportNsiListRequest"; // имя элемента в XML вместе с префиксом, в который следует добавить подпись, для СМЭВ-3 в общем случае "ns2:CallerInformationSystemSignature"
		String xmlElementID = "foo"; // ID элемента в XML (если присутствует) вместе с префиксом, на который следует поставить подпись, для СМЭВ-3 в общем случае "SIGNED_BY_CONSUMER"
		ByteArrayOutputStream bais=MakeXMLSign(data,xmlElementName,xmlElementID,x509Cert,privateKey);
	
		FileOutputStream outs = new FileOutputStream("signed_file.xml");
		outs.write(bais.toByteArray());
		outs.close();	

	}

}


Получается вот такая подпись:
my_sig.zip (4kb) загружен 1 раз(а).

Она отличается от той что в примере ГИС ЖКХ.
В ней меньше блоков Reference
в ней нет блока Object/QualifyingProperties
Подскажите в чем причина?
Как правильно сделать подпись для ГИС ЖКХ на JAVA с использованием ru.CryptoPro.JCPxml.xmldsig.JCPXMLDSigInit ?
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.