Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ 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 ?

Wanna join the discussion?! Login to your Форум КриптоПро forum account. Новые регистрации запрещены.

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