Алгоритм трансформации КриптоПро urn:xml-dsig:transformation:v1.1

216
20 мая 2018, 08:40

Всем привет! Кто нибудь сталкивался с самостоятельной реализацией верификации XML-подписи, подписанной через КриптоПро? Интересует алгоритм urn:xml-dsig:transformation:v1.1, он работает для проверки KeyValue, но валится на проверке Object'a

Ниже пример xml

<SignedInfo>
        <CanonicalizationMethod Algorithm="urn:xml-dsig:transformation:v1.1"/>
        <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"/>
        <Reference URI="#KeyInfo">
            <Transforms>
                <Transform Algorithm="urn:xml-dsig:transformation:v1.1"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411"/>
            <DigestValue>Dkud9a49mwRODp2obixe6Y3Uhjm/8yIMEe+QMCRA+pw=</DigestValue>
        </Reference>
        <Reference URI="#Object">
            <Transforms>
                <Transform Algorithm="urn:xml-dsig:transformation:v1.1"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411"/>
            <DigestValue>V7fttT6wI06Pa8f1HfZVQVz+t1Kh8eWkqUwz3Z2NLt0=</DigestValue>
        </Reference>
    </SignedInfo>
    <SignatureValue/>
    <KeyInfo Id="KeyInfo">
        <X509Data>
            <X509Certificate>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</X509Certificate>
        </X509Data>
    </KeyInfo>
    <Object Id="Object">
        <ArchCreateRequest DocumentModeID="1005002E" xmlns="urn:customs.ru:Information:EArchDocuments:ArchCreateRequest:5.12.0" xmlns:ct="urn:customs.ru:Information:EArchDocuments:EADCommonTypes:5.12.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <ct:DocumentID>BCB2F413-1565-4469-AD18-B5AF77CCBDB2</ct:DocumentID>
            <ArchiveName>ЛЮКССТАЛЬ ООО НЬЮ</ArchiveName>
            <ArchDeclID>102773904761094</ArchDeclID>
        </ArchCreateRequest>
    </Object>

И мой неоднозначный код без комментариев на Java

private SortedSet<String> namespaces = new TreeSet<String>();
private Map<String, String> namespacesWithPrefixesMap = new HashMap<String, String>();
private Node nodeElement;
private boolean normalized = false;
private static final String xmlnsNamespace = "http://www.w3.org/2000/xmlns/";
private static final String xmlSchemaInstanceNamespace = "http://www.w3.org/2001/XMLSchema-instance";
private static List<String> xmlSchemaAttributes = Arrays.asList("schemaLocation", "noNamespaceSchemaLocation",
        "type", "nil");
private int namespacesCount = 0;
public CryptoProNormalization(Node nodeElement) {
    try {
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        dbFactory.setNamespaceAware(true);
        DocumentBuilder builder;
        builder = dbFactory.newDocumentBuilder();
        Document dom = builder.newDocument();
        Node importedNode = dom.importNode(nodeElement, true);
        dom.appendChild(importedNode);
        this.nodeElement = dom.getDocumentElement();
    } catch (ParserConfigurationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
public Node normalize() {
    removeProcessInstructions();
    removeWrongAttributes();
    renameNamespaces();
    normalized = true;
    String resultNodeString = TestUtils.nodeToString((Node) nodeElement);
    return nodeElement;
}
private void removeProcessInstructions() {
    removeProcessInstructionsFromNode(nodeElement);
}
public static void removeProcessInstructionsFromNode(Node node) {
    NodeList list = node.getChildNodes();
    for (int i = 0; i < list.getLength(); i++) {
        removeProcessInstructionsFromNode(list.item(i));
    }
    if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
        System.out.println("remove node -> " + node.getTextContent());
        node.getParentNode().removeChild(node);
    }
}
private void removeWrongAttributes() {
    removeWrongAttributesFromNode(nodeElement);
}
private void removeWrongAttributesFromNode(Node node) {
    String oldNamespace = node.getNamespaceURI();
    NodeList list = node.getChildNodes();
    for (int i = 0; i < list.getLength(); i++) {
        removeWrongAttributesFromNode(list.item(i));
    }
    NamedNodeMap nnm = node.getAttributes();
    if (nnm == null)
        return;
    for (int i = 0; i < nnm.getLength(); i++) {
        Node currentNode = nnm.item(i);
        if (xmlSchemaInstanceNamespace.equals(currentNode.getNamespaceURI())
                && xmlSchemaAttributes.contains(currentNode.getLocalName())) {
            ((Element) node).removeAttribute(currentNode.getNodeName());
            System.out.println("removed attribute -> " + currentNode.getNodeName());
        }
    }
}
private void renameNamespaces() {
    collectNamespaces();
    createNewPrefixes();
    removeAllNamespacesAttributes();
    renameNamespacesWithNewPrefxes();
    // renameNamespacesInNode(nodeElement);
}
private void removeAllNamespacesAttributes() {
    removeAllNamespacesAttributesFromNode(nodeElement);
}
private void removeAllNamespacesAttributesFromNode(Node node) {
    NodeList list = node.getChildNodes();
    for (int i = 0; i < list.getLength(); i++) {
        removeAllNamespacesAttributesFromNode(list.item(i));
    }
    NamedNodeMap nnm = node.getAttributes();
    if (nnm != null) {
        int i = 0;
        while (i < nnm.getLength()) {
            Node currentNode = nnm.item(i);
            if (xmlnsNamespace.equals(currentNode.getNamespaceURI())) {
                ((Element) node).removeAttribute(currentNode.getNodeName());
                System.out.println("removed attribute -> " + currentNode.getNodeName());
            } else {
                i++;
            }
        }
    }
}
private void collectNamespaces() {
    collectNamespacesFromNode(nodeElement);
}
private void collectNamespacesFromNode(Node node) {
    NodeList list = node.getChildNodes();
    for (int i = 0; i < list.getLength(); i++) {
        collectNamespacesFromNode(list.item(i));
    }
    NamedNodeMap nnm = node.getAttributes();
    if (nnm != null) {
        for (int i = 0; i < nnm.getLength(); i++) {
            collectNamespacesFromNode(nnm.item(i));
        }
    }
    if (node.getNamespaceURI() != null) {
        if (!xmlnsNamespace.equals(node.getNamespaceURI())) {
            namespaces.add(node.getNamespaceURI());
        }
    }
}
private void createNewPrefixes() {
    Iterator<String> namespaceIterator = namespaces.iterator();
    while (namespaceIterator.hasNext()) {
        String prefix = "n" + (++namespacesCount);
        String namespace = namespaceIterator.next();
        namespacesWithPrefixesMap.put(namespace, prefix);
        ((Element) nodeElement).setAttribute("xmlns:" + prefix, namespace);
    }
}
private void renameNamespacesWithNewPrefxes() {
    renameNamespacesInNode(nodeElement);
}
private void renameNamespacesInNode(Node node) {
    NodeList list = node.getChildNodes();
    for (int i = 0; i < list.getLength(); i++) {
        renameNamespacesInNode(list.item(i));
    }
    NamedNodeMap nnm = node.getAttributes();
    if (nnm != null) {
        for (int i = 0; i < nnm.getLength(); i++) {
            renameNamespacesInNode(nnm.item(i));
        }
    }
    if (node.getNamespaceURI() != null) {
        node.setPrefix(namespacesWithPrefixesMap.get(node.getNamespaceURI()));
    }
}

Может я что то туплю? Сам алгоритм можно посмотреть тут: http://customs.ru/attachments/article/14243/ecp2.4.pdf

Всем мир труд май!

READ ALSO
Android: поменять значения каждого элемента

Android: поменять значения каждого элемента

Есть ListViev состоящий из TextViev, как можно зная позицию и id элемента, обратиться напрямую к каждому TextViev? Например поменять текст и задний фон...

188
Дизайн приложнения Android

Дизайн приложнения Android

Как сделать такие контейнерыОни как бы на поверхности и сзади серый фон и кажеться есть тень

210
Ошибка в конструкторе класса

Ошибка в конструкторе класса

Возникли проблемы с конструктором класса: Return type for the method is missingСам не вижу ошибки, поэтому прошу вас, будьте добры выручить

201
SimpleCursorAdapter управлением данными

SimpleCursorAdapter управлением данными

Записываю дату в бд в формате ддмм

196