Ver Mensaje Individual
  #5  
Antiguo 01-10-2020
Avatar de keys
keys keys is offline
Miembro
 
Registrado: sep 2003
Ubicación: Bilbao
Posts: 1.029
Reputación: 22
keys Va por buen camino
Hola a todos.

Como ya he comentado el problema radica que con este tipo de certificados de representación hay que firmar el fichero varias veces. Despues de varios días hablando con los de SecureBlackBox parece que hemos encontrado la solución. Pongo la solución para firmar con estos certificados y la anterior.

Código Delphi [-]
procedure SignFacturaRepresentacion(XMLDocument : TElXMLDOMDocument; Cert : TElX509Certificate);
var
Signer : TElXMLSigner;
XAdESSigner: TElXAdESSigner;
X509KeyInfoData: TElXMLKeyInfoX509Data;
DataFormat : TElXMLDataObjectFormat;
Ref : TElXMLReference;
URL : string;
Buf : ByteArray;
k, i : Integer;

CertificateValidator : TElX509CertificateValidator;
Validity : TSBCertificateValidity;
Reason   : TSBCertificateValidityReason;

begin

 Signer := TElXMLSigner.Create(nil);
 XAdESSigner := TElXAdESSigner.Create(nil);
 X509KeyInfoData := TElXMLKeyInfoX509Data.Create(true);
 try
  Signer.XAdESProcessor := XAdESSigner;
  Signer.SignatureMethodType := xmtSig;
  Signer.SignatureMethod := xsmRSA_SHA256;
  Signer.CanonicalizationMethod := xcmCanon;
  Signer.IncludeKey := true;

  k := Signer.References.Add;
  Ref := Signer.References[k];
  Ref.DigestMethod := xdmSHA512;
  Ref.ID := 'Ref1';
  Ref.URI := '';
  Ref.URINode := XMLDocument.DocumentElement;
  Ref.TransformChain.AddEnvelopedSignatureTransform();

  Signer.UpdateReferencesDigest();

  k := Signer.References.Add;
  Ref := Signer.References[k];
  Ref.DigestMethod := xdmSHA512;
  Ref.URI := '#Certificate1';

  XAdESSigner.XAdESVersion := XAdES_v1_3_2;
  XAdESSigner.Included := [xipSignerRole];
  XAdESSigner.SigningTime := UTCNow;
  XAdESSigner.SignerRole.ClaimedRoles.AddText(XAdESSigner.XAdESVersion, XMLDocument, 'emisor');

  URL := 'http://www.facturae.es/politica_de_firma_formato_facturae/politica_de_firma_formato_facturae_v3_1.pdf';
  XAdESSigner.PolicyId.SigPolicyId.Identifier := URL;
  XAdESSigner.PolicyId.SigPolicyId.IdentifierQualifier := xqtNone;
    XAdESSigner.PolicyId.SigPolicyHash.DigestMethod := DigestMethodToURI(xdmSHA1);

  XAdESSigner.PolicyId.SigPolicyHash.DigestValue := ConvertFromBase64String('Ohixl6upD6av8N7pEvDABhEL6hM=');

  XAdESSigner.SigningCertificates := TElMemoryCertStorage.Create(nil);
  XAdESSigner.OwnSigningCertificates := true;
  XAdESSigner.SigningCertificates.Add(Cert);

  XAdESSigner.SigningCertificatesDigestMethod := xdmSHA512;
  XAdESSigner.SignedPropertiesReferenceDigestMethod := xdmSHA512;

  XAdESSigner.Generate(XAdES_EPES);


  XAdESSigner.QualifyingProperties.XAdESPrefix := 'xades';
  XAdESSigner.QualifyingProperties.ID := 'QualifyingPropertiesId';


  DataFormat := TElXMLDataObjectFormat.Create(XAdESSigner.XAdESVersion);
  //DataFormat.Description := 'Factura electrónica';
  DataFormat.MimeType := 'text/xml';
  DataFormat.ObjectReference := '#Ref1';
  XAdESSigner.QualifyingProperties.SignedProperties.SignedDataObjectProperties.DataObjectFormats.Add(D  ataFormat);

  X509KeyInfoData.IncludeKeyValue := true;
  X509KeyInfoData.IncludeDataParams := [xkidX509Certificate];


  X509KeyInfoData.CertStorage := TElMemoryCertStorage.Create(nil);
  X509KeyInfoData.CertStorage.Add(Cert);


  CertificateValidator := TElX509CertificateValidator.Create(nil);
  CertificateValidator.CheckCRL := false;
  CertificateValidator.CheckOCSP := false;
  CertificateValidator.ImplicitlyTrustSelfSignedCertificates := true;
  CertificateValidator.Validate(cert, Validity, Reason);

  for i := 1 to (CertificateValidator.UsedCertificates.Count - 1) do
   begin
    X509KeyInfoData.CertStorage.Add(CertificateValidator.UsedCertificates.Certificates[i]);
   end;


  Signer.KeyData := X509KeyInfoData;

  Signer.GenerateSignature;
  Signer.Signature.KeyInfo.ID := 'Certificate1';

  Signer.SaveEnveloped(XMLDocument.DocumentElement);
  finally
   FreeAndNil(X509KeyInfoData);
   FreeAndNil(Signer);
   FreeAndNil(XAdESSigner);
   FreeAndNil(CertificateValidator);
  end;
end;

Código Delphi [-]
procedure SignFactura(XMLDocument : TElXMLDOMDocument; Cert : TElX509Certificate);
var
Signer : TElXMLSigner;
XAdESSigner: TElXAdESSigner;
X509KeyInfoData: TElXMLKeyInfoX509Data;
DataFormat : TElXMLDataObjectFormat;
Ref : TElXMLReference;
URL : string;
Buf : ByteArray;
k : Integer;
begin

 Signer := TElXMLSigner.Create(nil);
 XAdESSigner := TElXAdESSigner.Create(nil);
 X509KeyInfoData := TElXMLKeyInfoX509Data.Create(false);
 try
  Signer.XAdESProcessor := XAdESSigner;
  Signer.SignatureMethodType := xmtSig;
  Signer.SignatureMethod := xsmRSA_SHA256;
  Signer.CanonicalizationMethod := xcmCanon;
  Signer.IncludeKey := true;

  k := Signer.References.Add;
  Ref := Signer.References[k];
  Ref.DigestMethod := xdmSHA512;
  Ref.ID := 'Ref1';
  Ref.URI := '';
  Ref.URINode := XMLDocument.DocumentElement;
  Ref.TransformChain.AddEnvelopedSignatureTransform();

  Signer.UpdateReferencesDigest();

  k := Signer.References.Add;
  Ref := Signer.References[k];
  Ref.DigestMethod := xdmSHA512;
  Ref.URI := '#Certificate1';

  XAdESSigner.XAdESVersion := XAdES_v1_3_2;
  XAdESSigner.Included := [xipSignerRole];
  XAdESSigner.SigningTime := UTCNow;
  XAdESSigner.SignerRole.ClaimedRoles.AddText(XAdESSigner.XAdESVersion, XMLDocument, 'emisor');

  URL := 'http://www.facturae.es/politica_de_firma_formato_facturae/politica_de_firma_formato_facturae_v3_1.pdf';
  XAdESSigner.PolicyId.SigPolicyId.Identifier := URL;
  XAdESSigner.PolicyId.SigPolicyId.IdentifierQualifier := xqtNone;
  //XAdESSigner.PolicyId.SigPolicyId.Description := 'Política de Firma FacturaE v3.1';
  XAdESSigner.PolicyId.SigPolicyHash.DigestMethod := DigestMethodToURI(xdmSHA1);
  // uncomment to calculate a digest value or use precalculated value
  //Buf := DownloadData(URL);
  //XAdESSigner.PolicyId.SigPolicyHash.DigestValue := CalculateDigest(@Buf[0], Length(Buf), xdmSHA1);
  XAdESSigner.PolicyId.SigPolicyHash.DigestValue := ConvertFromBase64String('Ohixl6upD6av8N7pEvDABhEL6hM=');

  XAdESSigner.SigningCertificates := TElMemoryCertStorage.Create(nil);
  XAdESSigner.OwnSigningCertificates := true;
  XAdESSigner.SigningCertificates.Add(Cert);

  XAdESSigner.SigningCertificatesDigestMethod := xdmSHA512;
  XAdESSigner.SignedPropertiesReferenceDigestMethod := xdmSHA512;

  XAdESSigner.Generate(XAdES_EPES);


  XAdESSigner.QualifyingProperties.XAdESPrefix := 'xades';
  XAdESSigner.QualifyingProperties.ID := 'QualifyingPropertiesId';


  DataFormat := TElXMLDataObjectFormat.Create(XAdESSigner.XAdESVersion);
  //DataFormat.Description := 'Factura electrónica';
  DataFormat.MimeType := 'text/xml';
  DataFormat.ObjectReference := '#Ref1';
  XAdESSigner.QualifyingProperties.SignedProperties.SignedDataObjectProperties.DataObjectFormats.Add(D  ataFormat);

  X509KeyInfoData.IncludeKeyValue := true;
  X509KeyInfoData.IncludeDataParams := [xkidX509Certificate];
  X509KeyInfoData.Certificate := Cert;

  Signer.KeyData := X509KeyInfoData;

  Signer.GenerateSignature;
  Signer.Signature.KeyInfo.ID := 'Certificate1';

  Signer.SaveEnveloped(XMLDocument.DocumentElement);
  finally
   FreeAndNil(X509KeyInfoData);
   FreeAndNil(Signer);
   FreeAndNil(XAdESSigner);
  end;
end;

Antes de llamar a una función de firma u otra se mira si el certificado es de representación.

Código Delphi [-]
if AnsiPos(Ansiuppercase('REPRESENTACIÓN'), ANSIUPPERCASE(Cert.IssuerName.CommonName)) = 0  then
               SignFactura(FXMLDocument, FCertificate) //firmado de la manera anterior 
             else
               SignFacturaRepresentacion(FXMLDocument, FCertificate);

De todas formas todo esto viene por que facturas que antes daban correcto en la página de hacienda de facturae https://www.facturae.gob.es ahora dan incorrecto. He podido comprobar que en otras páginas del gobierno como https://face.gob.es/es/facturas/vali...lizar-facturas, las facturas siguen dando correcto. Asi que parece que es una validación que han añadido en la primera página.
Responder Con Cita