Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Envío de registros y sus respuestas (https://www.clubdelphi.com/foros/forumdisplay.php?f=66)
-   -   Ejemplo Registro de Eventos (https://www.clubdelphi.com/foros/showthread.php?t=97885)

Daviid 24-11-2025 09:39:34

Ejemplo Registro de Eventos
 
Alguien tiene un ejemplo de registro de evento? Firmado y sin firmar?

Creo que tengo uno pero VALIDe me da error, EADTrust también me falla.

Este código me sale todo bien, pero es ChatGPT así que....


Código:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Full XAdES-EPES validation script
# Validates:
#  - Canonicalization of SignedInfo
#  - Digest of SignedProperties
#  - Digest of the enveloped document
#  - SignatureValue (RSA-SHA256)
#  - Certificate used for signing
#  - XAdES EPES requirements: SigningCertificate, SignaturePolicyIdentifier

import base64
import hashlib
import urllib.request
from lxml import etree
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography import x509

XML_FILE = r"firmado.xml"

NS = {
    "ds": "http://www.w3.org/2000/09/xmldsig#",
    "xades": "http://uri.etsi.org/01903/v1.3.2#",
}

def c14n(node, with_comments=False):
    """Returns canonicalized XML for a node."""
    return etree.tostring(
        node,
        method="c14n",
        exclusive=True,
        with_comments=with_comments
    )

def sha256(data):
    return base64.b64encode(hashlib.sha256(data).digest()).decode()

def sha1(data):
    return base64.b64encode(hashlib.sha1(data).digest()).decode()

def load_xml():
    parser = etree.XMLParser(remove_blank_text=True)
    return etree.parse(XML_FILE, parser)

def extract_certificate(cert_b64):
    cert_bytes = base64.b64decode(cert_b64)
    return x509.load_der_x509_certificate(cert_bytes)

def validate_reference_digest(node, expected_digest):
    canon = c14n(node)
    digest = sha256(canon)
    return digest == expected_digest, digest

def validate_signature_value(public_key, signed_info_c14n, signature_value):
    try:
        public_key.verify(
            signature_value,
            signed_info_c14n,
            padding.PKCS1v15(),
            hashes.SHA256()
        )
        return True
    except Exception:
        return False

def main():
    print("Loading XML…")
    doc = load_xml()

    signature = doc.find(".//ds:Signature", NS)
    signed_info = signature.find("ds:SignedInfo", NS)
    signature_value_el = signature.find("ds:SignatureValue", NS)
    key_info = signature.find("ds:KeyInfo/ds:X509Data/ds:X509Certificate", NS)

    # Extract certificate
    cert_b64 = key_info.text.strip()
    cert = extract_certificate(cert_b64)
    public_key = cert.public_key()

    # Canonicalize SignedInfo
    signed_info_c14n = c14n(signed_info)

    # Decode SignatureValue
    signature_value = base64.b64decode(signature_value_el.text.strip())

    print("\n=== Step 1: Validate SignatureValue (RSA-SHA256) ===")
    if validate_signature_value(public_key, signed_info_c14n, signature_value):
        print("✔ SignatureValue is VALID")
    else:
        print("✘ SignatureValue is INVALID")

    print("\n=== Step 2: Validate each Reference digest ===")
    references = signed_info.findall("ds:Reference", NS)
    for ref in references:
        uri = ref.get("URI")
        expected_digest = ref.find("ds:DigestValue", NS).text.strip()

        if uri.startswith("#"):
            target_id = uri[1:]
            target = doc.find(f".//*[@Id='{target_id}']")
        else:
            # Empty URI => enveloped signing of root element
            target = doc.getroot()

        # Root must exclude the <Signature> itself (enveloped signature transform)
        transforms = ref.find("ds:Transforms", NS)
        if transforms is not None:
            for t in transforms.findall("ds:Transform", NS):
                algo = t.get("Algorithm")
                if algo == "http://www.w3.org/2000/09/xmldsig#enveloped-signature":
                    sig_node = signature
                    sig_node.getparent().remove(sig_node)

        valid, computed_digest = validate_reference_digest(target, expected_digest)

        print(f"\nReference URI='{uri}'")
        print(f"Expected digest: {expected_digest}")
        print(f"Computed digest: {computed_digest}")
        print("✔ Digest VALID" if valid else "✘ Digest INVALID")

    print("\n=== Step 3: Validate XAdES SignedProperties digest ===")
    signed_props_ref = signature.find(
        "ds:SignedInfo/ds:Reference[@Type='http://uri.etsi.org/01903#SignedProperties']",
        NS
    )
    if signed_props_ref is not None:
        uri = signed_props_ref.get("URI")[1:]
        expected_digest = signed_props_ref.find("ds:DigestValue", NS).text.strip()

        signed_props = signature.find(
            f"ds:Object/xades:QualifyingProperties/xades:SignedProperties[@Id='{uri}']",
            NS
        )
        valid, computed_digest = validate_reference_digest(signed_props, expected_digest)

        print(f"Expected: {expected_digest}")
        print(f"Computed: {computed_digest}")
        print("✔ SignedProperties digest VALID" if valid else "✘ SignedProperties digest INVALID")

    print("\n=== Step 4: Validate SigningCertificate digest (XAdES requirement) ===")
    signing_cert = signature.find(
        "ds:Object/xades:QualifyingProperties/xades:SignedProperties/"
        "xades:SignedSignatureProperties/xades:SigningCertificate/"
        "xades:Cert/xades:CertDigest/ds:DigestValue",
        NS
    )

    method = signature.find(
        "ds:Object/xades:QualifyingProperties/xades:SignedProperties/"
        "xades:SignedSignatureProperties/xades:SigningCertificate/"
        "xades:Cert/xades:CertDigest/ds:DigestMethod",
        NS
    ).get("Algorithm")

    expected_cert_digest = signing_cert.text.strip()

    if method == "http://www.w3.org/2000/09/xmldsig#sha1":
        computed_cert_digest = sha1(cert.public_bytes(serialization.Encoding.DER))
    else:
        computed_cert_digest = sha256(cert.public_bytes(serialization.Encoding.DER))

    print(f"Expected: {expected_cert_digest}")
    print(f"Computed: {computed_cert_digest}")
    if expected_cert_digest == computed_cert_digest:
        print("✔ SigningCertificate digest VALID")
    else:
        print("✘ SigningCertificate digest INVALID")

    print("\n=== Step 5: Validate XAdES SignaturePolicyHash (EPES) ===")
    policy_hash_el = signature.find(
        "ds:Object/xades:QualifyingProperties/xades:SignedProperties/"
        "xades:SignedSignatureProperties/xades:SignaturePolicyIdentifier/"
        "xades:SignaturePolicyId/xades:SigPolicyHash/ds:DigestValue",
        NS
    )
    policy_method = signature.find(
        "ds:Object/xades:QualifyingProperties/xades:SignedProperties/"
        "xades:SignedSignatureProperties/xades:SignaturePolicyIdentifier/"
        "xades:SignaturePolicyId/xades:SigPolicyHash/ds:DigestMethod",
        NS
    ).get("Algorithm")

    expected_policy_hash = policy_hash_el.text.strip()

    print(f"Policy digest given in XML: {expected_policy_hash}")
    print(f"Digest method: {policy_method}")

    print("\nValidating policy hash...")
    policy_identifier_el = signature.find(
        "ds:Object/xades:QualifyingProperties/xades:SignedProperties/"
        "xades:SignedSignatureProperties/xades:SignaturePolicyIdentifier/"
        "xades:SignaturePolicyId/xades:SigPolicyId/xades:Identifier",
        NS
    )
    if policy_identifier_el is None:
        print("✘ No policy identifier found")
    else:
        policy_identifier = policy_identifier_el.text.strip()
        print(f"Policy Identifier: {policy_identifier}")
        try:
            if policy_identifier.startswith("urn:oid:"):
                if policy_identifier == "urn:oid:2.16.724.1.3.1.1.2.1.9":
                    policy_url = "https://sede.administracion.gob.es/politica_de_firma_anexo_1.pdf"
                else:
                    raise ValueError(f"Unknown OID: {policy_identifier}")
            else:
                policy_url = policy_identifier

            with urllib.request.urlopen(policy_url) as response:
                policy_data = response.read()
            if policy_method == "http://www.w3.org/2000/09/xmldsig#sha1":
                computed_hash = base64.b64encode(hashlib.sha1(policy_data).digest()).decode()
            elif policy_method == "http://www.w3.org/2001/04/xmlenc#sha256":
                computed_hash = base64.b64encode(hashlib.sha256(policy_data).digest()).decode()
            else:
                print(f"Unsupported digest method: {policy_method}")
                computed_hash = None
            if computed_hash:
                print(f"Computed policy hash: {computed_hash}")
                if computed_hash == expected_policy_hash:
                    print("✔ Policy hash VALID")
                else:
                    print("✘ Policy hash INVALID")
        except Exception as e:
            print(f"Error fetching or computing policy hash: {e}")


    print("\n=== VALIDATION FINISHED ===")


if __name__ == "__main__":
    main()


Neftali [Germán.Estévez] 24-11-2025 15:50:14

Cita:

Empezado por Daviid (Mensaje 570161)
Alguien tiene un ejemplo de registro de evento? Firmado y sin firmar?

Revisad la Guía de estilo de los foros.
Importante hacer una simple búsqueda antes de preguntar:
https://www.clubdelphi.com/foros/showthread.php?t=97401
https://www.clubdelphi.com/foros/showthread.php?t=97210

Daviid 25-11-2025 08:18:44

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 570208)


Pensaba que estos no me servían por que mi error esta en la firma, pero ya he arreglado mi error, por hacer copiar y pegar estaba usando xml-exc-c14n# en lugar de REC-xml-c14n-20010315 :p

Y luego no se si tambien afectaba el

<xades:SPURI>

Que en https://sede.administracion.gob.es/p...ma_anexo_1.pdf pone una URL y en https://administracionelectronica.go...dElemento=2854 otra


Pongo mi propio XML de evento con la firma, modificando hashes, digests y datos personales.

Código:

<?xml version="1.0" encoding="UTF-8"?>
<sum1:RegistroEvento
        xmlns:sum1="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd">
        <sum1:IDVersion>1.0</sum1:IDVersion>
        <sum1:SistemaInformatico>
                <sum1:NombreSistemaInformatico>ERP/CRM</sum1:NombreSistemaInformatico>
                <sum1:IdSistemaInformatico>67</sum1:IdSistemaInformatico>
                <sum1:Version>2.3</sum1:Version>
                <sum1:NumeroInstalacion>1234</sum1:NumeroInstalacion>
        </sum1:SistemaInformatico>
        <sum1:ObligadoEmision>
                <sum1:NombreRazon>EMPRESA SL</sum1:NombreRazon>
                <sum1:NIF>X1234567</sum1:NIF>
        </sum1:ObligadoEmision>
        <sum1:FechaHoraHusoGenEvento>2025-11-24T16:12:18+01:00</sum1:FechaHoraHusoGenEvento>
        <sum1:TipoEvento>90</sum1:TipoEvento>
        <sum1:DatosPropiosEvento>
                <sum1:Descripcion>Configuración actualizada. Parámetro: xxxxxx Valor: *</sum1:Descripcion>
        </sum1:DatosPropiosEvento>
        <sum1:Encadenamiento>
                <sum1:EventoAnterior>
                        <sum1:TipoEvento>90</sum1:TipoEvento>
                        <sum1:FechaHoraHusoGenEvento>2025-11-24T16:12:18+01:00</sum1:FechaHoraHusoGenEvento>
                        <sum1:HuellaEvento>4103A5C159FE9372JHSD9U712HWI080EF141318931D3A44E920C4D9EC2</sum1:HuellaEvento>
                </sum1:EventoAnterior>
        </sum1:Encadenamiento>
        <sum1:TipoHuella>01</sum1:TipoHuella>
        <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
                xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" Id="Signature-3203e562ebbc126c8018">
                <ds:SignedInfo>
                        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
                        <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
                        <ds:Reference URI="#Signature-3203e562ebbc126c8018-SignedProperties"
                                Type="http://uri.etsi.org/01903#SignedProperties">
                                <ds:Transforms>
                                        <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
                                </ds:Transforms>
                                <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                                <ds:DigestValue>Zj/HHiE/qL6rHoscdfvwedsaseurimHQ78U2euqU=</ds:DigestValue>
                        </ds:Reference>
                        <ds:Reference URI="" Id="Signature-3203e562ebbc126c8018-ref0">
                                <ds:Transforms>
                                        <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                                </ds:Transforms>
                                <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                                <ds:DigestValue>LSiz7c5HYfuXSdgberfvwed/SExdQ52j7UVRjbtCcwfDQ=</ds:DigestValue>
                        </ds:Reference>
                </ds:SignedInfo>
                <ds:SignatureValue>
                        EM3pYSoXZrZW2zQ......................rpRcPehHuuXdeykI0g==</ds:SignatureValue>
                <ds:KeyInfo>
                        <ds:X509Data>
                                <ds:X509Certificate>
                                        MIIIgjCCB2qg..........+M10jKKOivmxd4N92ZfRmZiXiY1PgH9XW1ohAKTA3cKmlO/hDYfW0YliJXNkpM7nnrZQr/+RynW+ra01EnCg==</ds:X509Certificate>
                        </ds:X509Data>
                </ds:KeyInfo>
                <ds:Object>
                        <xades:QualifyingProperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#"
                                Target="#Signature-3203e562ebbc126c8018">
                                <xades:SignedProperties Id="Signature-3203e562ebbc126c8018-SignedProperties">
                                        <xades:SignedSignatureProperties>
                                                <xades:SigningTime>2025-11-24T15:12:18Z</xades:SigningTime>
                                                <xades:SigningCertificate>
                                                        <xades:Cert>
                                                                <xades:CertDigest>
                                                                        <ds:DigestMethod
                                                                                Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                                                                        <ds:DigestValue>AKngdfgasdsdfc4+sXcrAEQty3mo0=</ds:DigestValue>
                                                                </xades:CertDigest>
                                                                <xades:IssuerSerial>
                                                                        <ds:X509IssuerName>CN=AC Representación, OU=CERES, O=FNMT-RCM,
                                                                                C=ES</ds:X509IssuerName>
                                                                        <ds:X509SerialNumber>83274923649826349702346290374629837462</ds:X509SerialNumber>
                                                                </xades:IssuerSerial>
                                                        </xades:Cert>
                                                </xades:SigningCertificate>
                                                <xades:SignaturePolicyIdentifier>
                                                        <xades:SignaturePolicyId>
                                                                <xades:SigPolicyId>
                                                                        <xades:Identifier Qualifier="OIDAsURN">
                                                                                urn:oid:2.16.724.1.3.1.1.2.1.9</xades:Identifier>
                                                                        <xades:Description>Política de firma electrónica utilizada en la
                                                                                Administración General del Estado</xades:Description>
                                                                </xades:SigPolicyId>
                                                                <xades:SigPolicyHash>
                                                                        <ds:DigestMethod
                                                                                Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                                                                        <ds:DigestValue>G7roucf600+f03r/o0bAOQ6WAs0=</ds:DigestValue>
                                                                </xades:SigPolicyHash>
                                                                <xades:SigPolicyQualifiers>
                                                                        <xades:SigPolicyQualifier>
                                                                                <xades:SPURI>
                                                                                        https://sede.administracion.gob.es/politica_de_firma_anexo_1.pdf</xades:SPURI>
                                                                        </xades:SigPolicyQualifier>
                                                                </xades:SigPolicyQualifiers>
                                                        </xades:SignaturePolicyId>
                                                </xades:SignaturePolicyIdentifier>
                                        </xades:SignedSignatureProperties>
                                        <xades:SignedDataObjectProperties>
                                                <xades:DataObjectFormat
                                                        ObjectReference="#Signature-3203e562ebbc126c8018-ref0">
                                                        <xades:ObjectIdentifier>
                                                                <xades:Identifier>urn:oid:1.2.840.10003.5.109.10</xades:Identifier>
                                                                <xades:Description />
                                                        </xades:ObjectIdentifier>
                                                        <xades:MimeType>text/xml</xades:MimeType>
                                                        <xades:Encoding>UTF-8</xades:Encoding>
                                                </xades:DataObjectFormat>
                                        </xades:SignedDataObjectProperties>
                                </xades:SignedProperties>
                        </xades:QualifyingProperties>
                </ds:Object>
        </ds:Signature>
</sum1:RegistroEvento>



La franja horaria es GMT +2. Ahora son las 06:30:36.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi