Всем привет! Кто нибудь сталкивался с самостоятельной реализацией верификации 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
Всем мир труд май!
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Есть ListViev состоящий из TextViev, как можно зная позицию и id элемента, обратиться напрямую к каждому TextViev? Например поменять текст и задний фон...
Как сделать такие контейнерыОни как бы на поверхности и сзади серый фон и кажеться есть тень
Возникли проблемы с конструктором класса: Return type for the method is missingСам не вижу ошибки, поэтому прошу вас, будьте добры выручить