A .NET interface for FirmaSAT
| Class | Description |
|---|---|
| General | General utilities. |
| Sat | SAT-related methods. |
| Tfd | Methods for Timbre Fiscal Digital (TFD). |
| Enumeration | Description |
|---|---|
| KeyFormat | Format for saved key files. |
| KeyOption | Options for key output in Sat.GetKeyAsString(). |
| PfxFormat | Options for PKCS12 (PFX) output in Sat.WritePfxFile(). |
| Query | Options for certificate query. |
| SignOptions | Options for signing XML. |
| XmlOption | Options for XML validation. |
General utilities.
System.Object
FirmaSAT.General
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public class GeneralThe General type exposes the following members.
| Name | Description |
|---|---|
| Comments | Get additional information about the core DLL module. |
| CompileTime | Get date and time the core DLL module was last compiled. |
| ErrorLookup | Look up error code. |
| FormatErrorMessage | Return an error message string for the last error. |
| LastError | Retrieve the last error message. |
| LicenceType | Get licence type. |
| ModuleName | Get full path name of core diFirmaSat DLL module. |
| Platform | Get the platform for which the core native DLL was compiled. |
| Version | Return version number of core diFirmaSat DLL. |
Get additional information about the core DLL module.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string Comments()String
Comments string
Console.WriteLine(General.Comments());
// Licensed Developer Edition | Edicion de Desarrollador Licenciado.General Class
FirmaSAT Namespace
Get date and time the core DLL module was last compiled.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string CompileTime()String
Date and time string.
Console.WriteLine(General.CompileTime()); // Feb 28 2021 18:29:46General Class
FirmaSAT Namespace
Look up error code.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string ErrorLookup(
int errCode
)Code number (may be positive or negative)
String
Corresponding error message
Console.WriteLine(General.ErrorLookup(-10));
// Required data not found/Datos necesarios no encontrados (MISSING_ERROR)General Class
FirmaSAT Namespace
Return an error message string for the last error.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string FormatErrorMessage(
int errCode = 0
)Error code returned by last call (optional)
String
Error message as a string
Error ({errCode}): {errorlookup}[: {lasterror}]
// Error (-28): XML restriction is violated/XML restriccion es violada (XML_FACET_ERROR):
// Bad attribute/atributo mal [iedu:instEducativas/@CURP] (line 30):
// 'JUAN01010101GTOHMD0' is too long/es demasiado largo, maximum length/longitud maxima=18General Class
FirmaSAT Namespace
Retrieve the last error message.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string LastError()String
Error message from last call (may be empty)
Call this immediately when an error is indicated. Calling another method will overwrite the message. This is the same as Sat.LastError().
int n = Sat.ValidateXml("cfdv33a-badspec.xml");
Console.WriteLine("Sat.ValidateXml returns {0}", n);
// Sat.ValidateXml returns -27
Console.WriteLine(General.ErrorLookup(n));
// Invalid XML format/No valido formato XML (BAD_XML_ERROR)
Console.WriteLine(General.LastError());
// XML validation error/Error al validar XML: Required attribute 'Importe' missing for element 'cfdi:Concepto' (Line/numero de linea: 12);
// XML validation error/Error al validar XML: Required attribute 'Importe' missing for element 'cfdi:Concepto' (Line/numero de linea: 13)General Class
FirmaSAT Namespace
FormatErrorMessage(Int32)
Retrieve the last error message.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string LastError()String
Error message from last call (may be empty)
Call this immediately when an error is indicated. Calling another method will overwrite the message. This is the same as General.LastError().
// Attempt to sign but input file does not comply with CFDi specifications
int n = satSignXml("cfdv33a-out.xml", "cfdv33a-badspec.xml", "emisor.key", "12345678a", "emisor.cer");
Console.WriteLine("Error {0}: {1}", n, Sat.ErrorLookup(n));
// Error -10: Required data not found/Datos necesarios no encontrados (MISSING_ERROR)
Console.WriteLine(Sat.LastError());
// Attribute 'Importe' is mandatory/Atributo es obligatorioSat Class
FirmaSAT Namespace
FormatErrorMessage(Int32)
Get licence type.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static char LicenceType()Char
D=Developer T=Trial
General Class
FirmaSAT Namespace
Get full path name of core diFirmaSat DLL module.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string ModuleName()String
File path.
Console.WriteLine(General.ModuleName()); // C:\WINDOWS\SYSTEM32\diFirmaSAT2.dllGeneral Class
FirmaSAT Namespace
Get the platform for which the core native DLL was compiled.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string Platform()String
"Win32" or "Win64"
General Class
FirmaSAT Namespace
Return version number of core diFirmaSat DLL.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static int Version()Int32
Version number in form
Major*10000 + Minor*100 + Release
For example, version 9.2.15 returns 90215
int n = General.Version();
Console.WriteLine("Version = {0}", n); // Version = 90215General Class
FirmaSAT Namespace
SAT-related methods.
System.Object
FirmaSAT.Sat
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public class SatThe Sat type exposes the following members.
| Name | Description |
|---|---|
| Asciify(Byte[]) | Replace any non-ASCII characters in an XML document (as a byte array) with XML character references (where permitted). |
| Asciify(String) | Replace non-ASCII characters in an XML document with XML numeric character references (where permitted). |
| CheckKeyAndCert | Verify that the public key in an X.509 certificate matches the private key. |
| DefaultDigestAlg | Return default digest (hash) algorithm for the XML document type. |
| ExtractDigestFromSignature | Extract message digest from the signature (sello) in an XML file. |
| FixBom | Add UTF-8 byte order mark (BOM) to a file if not already present. |
| GetCertAsString | Get certificate data as a base64 string. |
| GetCertExpiry | Get expiry date of the X.509 certificate in ISO time format. |
| GetCertNumber | Get serial number of the X.509 certificate in “special” SAT format. |
| GetCertStart | Get start date of the X.509 certificate in ISO time format. |
| GetKeyAsString | Get private key data as a base64 string suitable for a
llaveCertificado element in a Cancelacion XML
document |
| GetXmlAttribute | Extract attribute data from an XML file. |
| InsertCert | Insert certificate information into an XML document and output to a new file. |
| InsertCertToBytes(Byte[], String) | Insert certificate information into an XML document (as a byte array) and output to memory. |
| InsertCertToBytes(String, String) | Insert certificate information into an XML document (as a file) and output to memory. |
| LastError | Retrieve the last error message. |
| MakeDigestFromXml | Form message digest of piped string (cadena) from an XML file. |
| MakePipeStringFromXml | Create the piped string (cadena) from an XML file. |
| MakeSignatureFromXml | Create signature as a base64 string from data in an XML file ready
to be inserted as a sello node. |
| NewKeyFile | Save keyfile with a new password. |
| QueryCert | Query an X.509 certificate. |
| SetXmlNoMatch | Modify the string returned when GetXmlAttribute(String, String, String) fails to find a match. |
| SignXml | Sign an XML file |
| SignXmlEx | Obsolete. Sign an XML file with extended options [deprecated]. |
| SignXmlToBytes(Byte[], String, String, String, SignOptions) | Sign XML data writing output to a byte array. |
| SignXmlToBytes(String, String, String, String, SignOptions) | Sign XML file writing output to a byte array. |
| Uuid | Generate a Universally Unique IDentifier (UUID) compliant with RFC 4122. |
| ValidateXml | Validate an XML file against SAT specifications. |
| VerifySignature | Verify the signature (sello) in an XML file. |
| WritePfxFile | Create PFX (PKCS-12) file in PEM format suitable for a Cancelación. |
| XmlNoMatch | Error message returned when GetXmlAttribute(String, String, String) fails to find a match |
| XmlReceiptVersion | Find version number of Comprobante element or ID number for other document types. |
Replace any non-ASCII characters in an XML document (as a byte array) with XML character references (where permitted).
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
| Name | Description |
|---|---|
| Asciify(Byte[]) | Replace any non-ASCII characters in an XML document (as a byte array) with XML character references (where permitted). |
| Asciify(String) | Replace non-ASCII characters in an XML document with XML numeric character references (where permitted). |
public static string Asciify(
byte[] xmlData
)Byte array containing XML data
String
XML document as a string with non-ASCII characters replaced by XML
character references.
(bytes) –> (string)
byte[] b = File.ReadAllBytes("cfdv40-ejemplo.xml");
string s = Sat.Asciify(b);
Console.WriteLine(s);
// <?xml version="1.0"?>
// <cfdi:Comprobante ... >
// <cfdi:Emisor Rfc=" AAA010101AAA" Nombre="Esta es una demostración" RegimenFiscal="622"></cfdi:Emisor>
// ... [etc]Replace non-ASCII characters in an XML document with XML numeric character references (where permitted).
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
| Name | Description |
|---|---|
| Asciify(Byte[]) | Replace any non-ASCII characters in an XML document (as a byte array) with XML character references (where permitted). |
| Asciify(String) | Replace non-ASCII characters in an XML document with XML numeric character references (where permitted). |
public static string Asciify(
string xmlFile
)Name of XML file (or a string containing XML data)
String
XML document as a string with non-ASCII characters replaced by XML
numeric character references.
In almost all cases, the output contains only US-ASCII characters and can safely be used as input to other functions without concern for character encoding issues. For example, the character “ó” (U+00F3 LATIN SMALL LETTER O WITH ACUTE) is replaced by the XML character reference “ó”.
In certain cases, some characters in an XML document cannot be
replaced by a numeric character reference, for example where they are
used in an element or attribute name, such as Año="2016".
In these cases, they are left as UTF-8-encoded characters.
Console.WriteLine(Sat.Asciify("cfdv40-ejemplo.xml");
// <?xml version="1.0" ?>
// <cfdi:Comprobante ... >
// <cfdi:Emisor Rfc=" AAA010101AAA" Nombre="Esta es una demostración" RegimenFiscal="622"></cfdi:Emisor>
// ... [etc]Verify that the public key in an X.509 certificate matches the private key.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static int CheckKeyAndCert(
string keyFile,
string password,
string certFile
)Name of private key file
Password for encrypted private key
X.509 certificate file or XML document with embedded
certificado node
Int32
Zero (0) if keys match or a negative error
code.
int n = Sat.CheckKeyAndCert("emisor.key", "12345678a", "emisor.cer");
Console.WriteLine("Sat.CheckKeyAndCert returns {0}", n);
// Sat.CheckKeyAndCert returns 0
// Cert and key do not match ...
n = Sat.CheckKeyAndCert("emisor.key", "12345678a", "pac.cer");
Console.WriteLine("Sat.CheckKeyAndCert returns {0}", n);
// Sat.CheckKeyAndCert returns -21
Console.WriteLine(General.ErrorLookup(n));
// Match not found/No se pudo encontrar datos coincidente (NO_MATCH_ERROR)
Console.WriteLine(General.LastError());
// Private key does not match key in certificate/La clave privada no coincide con la clave del certificadoReturn default digest (hash) algorithm for the XML document type.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string DefaultDigestAlg(
string xmlFile
)Name of XML file
String
“SHA-1” or “SHA-256”; or “!ERROR!” if an error occurred.
Console.WriteLine(Sat.DefaultDigestAlg("cfdv40-ejemplo.xml")); // SHA-256Extract message digest from the signature (sello) in an XML file.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string ExtractDigestFromSignature(
string xmlFile,
string certFile = ""
)Name of input XML file to be processed (or a string containing XML data)
X.509 certificate file (optional) to override embedded Certificado node.
String
Message digest in hex format or empty string on error
This is the actual digest value computed over the original document and used to sign it. To re-compute the digest value over the current document, use MakeDigestFromXml(String).
Console.WriteLine(Sat.ExtractDigestFromSignature("cfdv40-ejemplo-signed-tfd.xml"));
// 0FF1274E51FBB090489588D832BB1B5B36543302DECBB0A5490839B8C99E8755Add UTF-8 byte order mark (BOM) to a file if not already present.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static int FixBom(
string outputFile,
string inputFile
)Name of output file to be created with BOM.
Name of input file.
Int32
Zero (0) on success or a negative error
code.
It is an error if the input file contains invalid UTF-8 characters.
int n = Sat.FixBom("cfdv40_new-signed-with-BOM.xml", "cfdv40-signed-nobom.xml");
Console.WriteLine("Sat.FixBom returns {0}", n);
// Read in new file as bytes, truncate, and display first 3 bytes: expecting EF-BB-BF
byte[] b = File.ReadAllBytes("cfdv40_new-signed-with-BOM.xml");
Array.Resize(ref b, 3);
Console.WriteLine(BitConverter.ToString(b));
// EF-BB-BFGet certificate data as a base64 string.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string GetCertAsString(
string fileName
)X.509 certificate file or XML file with Certificado
node
String
Certificate data as a string of base64 characters
Use to obtain the value for the Certificado node from a
.CER file. If input is an XML file, this is equivalent to
Sat.GetXmlAttribute(fileName, "Certificado", "Comprobante")
Console.WriteLine(Sat.GetCertAsString("emisor.cer"));
// MIIF+TCCA+GgAwIBAgIUMzAwMDEwMDAwMDAzMDAw ...Get expiry date of the X.509 certificate in ISO time format.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string GetCertExpiry(
string fileName
)X.509 certificate file or XML file with certificado
node
String
Certificate expiry date
Console.WriteLine(Sat.GetCertExpiry("emisor.cer"));
// 2021-05-18T03:54:56ZGet serial number of the X.509 certificate in “special” SAT format.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string GetCertNumber(
string fileName
)X.509 certificate file or XML file with certificado
node
String
Certificate serial number
Expected format is 20 decimal digits encoded in ASCII format
// From certificate file directly
Console.WriteLine(Sat.GetCertNumber("emisor.cer"));
// 30001000000300023708
// From embedded Certificado attribute
Console.WriteLine(Sat.GetCertNumber("cfdv40-ejemplo-signed-tfd.xml"));
// 30001000000300023708Get start date of the X.509 certificate in ISO time format.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string GetCertStart(
string fileName
)X.509 certificate file or XML file with certificado
node
String
Certificate start date
Console.WriteLine(Sat.GetCertStart("emisor.cer"));
// 2017-05-18T03:54:56ZExtract attribute data from an XML file.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string GetXmlAttribute(
string xmlFile,
string attributeName,
string elementName
)Name of input XML file to be processed (or a string containing XML data)
Name of attribute
Name of element or xpath expression (see remarks)
String
Attribute value, if found; or "!NO MATCH!" if not found
(see XmlNoMatch()); or empty string on
error (the empty string may be the correct result if
attr="", so check for an error using LastError()).
For a simple element name, the default behaviour is to get the
attribute from the first element found with the given name. Specify the
element name in the form "element[N]" to extract the
attribute for the N’th element found in the XML document, where
N is a positive decimal integer (N=1,2,3,...).
Setting elementName="" will output the value of the named
attribute from the root element of the XML document. Setting both
elementName="" and attributeName="" will
output the name of the root element itself.
XPath expression: Alternatively, specify an path
expression in elementName using the "/" and
"//" operators and optional predicate [N]
where N is a positive integer. For example
"/Comprobante/Emisor" or
"//Concepto[2]//Retencion[3]". This is a simplified form of
XPath that selects the first occurrence of the element matching the path
expression (whereas XPath would select all matching elements). Path
expressions must start with a "/" or "//" and
must not end with a "/". No other XPath function or
operator is accepted. Do not use namespace prefixes
(e.g. "cfdi:") in the path expression.
Simplified Xpath syntax: /e1 – selects
the first <e1> document element (child element of the
document node)./e1/e2 – selects the first
<e2> child element of the first
<e1> document element./e1[2]/e2[3] –
selects the third <e2> child element of the second <e1>
document element./e1[1]/e2[1] – same as
/e1/e2.//e2 – the first
<e2> element found anywhere (same as simple
e2).//e2[3] – the third
<e2> element found anywhere (same as simple
e2[3])./e1//e2 – the first
<e2> element found anywhere inside the
<e1> element. To test for the existence of an
element, set attributeName="". This will return the name of
the element if it exists, or "!NO MATCH!" if not found.
This message can be changed using SetXmlNoMatch(String).
Console.WriteLine(Sat.GetXmlAttribute("cfdv40-ejemplo.xml", "Nombre", "cfdi:Emisor"));
// Esta es una demostraciónSat Class
FirmaSAT Namespace
XmlNoMatch()
SetXmlNoMatch(String)
Insert certificate information into an XML document and output to a new file.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static int InsertCert(
string newFile,
string baseFile,
string certFile
)Name of new file to be created.
Name of input XML file to be processed (or a string containing XML data).
X.509 certificate file.
Int32
0 if successful or non-zero error code
if failed
// Take an XML file without a NoCertificado...
string fname = cfdv40-ejemplo-nocertnum.xml";
Console.WriteLine("Start file '{0}'.NoCertificado=[{1}]", fname, Sat.GetXmlAttribute(fname, "NoCertificado", "cfdi:Comprobante"));
Console.WriteLine("Start file '{0}'.Certificado={1} bytes", fname, Sat.GetXmlAttribute(fname, "Certificado", "cfdi:Comprobante").Length);
// Insert certificate details into intermediate file...
string interfile = "cfdv40_new-base-pluscert.xml";
int n = Sat.InsertCert(interfile, fname, "emisor.cer");
Console.WriteLine("Sat.InsertCert() returns {0} (expecting 0)", n);
Debug.Assert(0 == n, "Sat.InsertCert failed");
Console.WriteLine("Inter file '{0}'.NoCertificado=[{1}]", interfile, Sat.GetXmlAttribute(interfile, "NoCertificado", "cfdi:Comprobante"));
Console.WriteLine("Inter file '{0}'.Certificado={1} bytes", interfile, Sat.GetXmlAttribute(interfile, "Certificado", "cfdi:Comprobante").Length);
// Start file 'cfdv40-ejemplo-nocertnum.xml'.NoCertificado=[]
// Start file 'cfdv40-ejemplo-nocertnum.xml'.Certificado=0 bytes
// Sat.InsertCert() returns 0 (expecting 0)
// Inter file 'cfdv40_new-base-pluscert.xml'.NoCertificado=[30001000000300023708]
// Inter file 'cfdv40_new-base-pluscert.xml'.Certificado=1836 bytesInsert certificate information into an XML document (as a byte array) and output to memory.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
| Name | Description |
|---|---|
| InsertCertToBytes(Byte[], String) | Insert certificate information into an XML document (as a byte array) and output to memory. |
| InsertCertToBytes(String, String) | Insert certificate information into an XML document (as a file) and output to memory. |
public static byte[] InsertCertToBytes(
byte[] xmlData,
string certFile
)Byte array containing XML data
X.509 certificate file
Byte[]
XML data as a byte array.
(bytes) –> (bytes)
// Pass input XML data as a byte array
byte[] xmlArr = File.ReadAllBytes("cfdv40-ejemplo-nocertnum.xml");
string cerStr = Sat.GetCertAsString("emisor.cer");
byte[] b = Sat.InsertCertToBytes(xmlArr, cerStr);
Console.WriteLine(System.Text.Encoding.UTF8.GetString(b));
// <cfdi:Comprobante
// ...
// NoCertificado="30001000000300023708" Sello="" Certificado="MIIF+TCCA+GgAwIBAgIU ...Insert certificate information into an XML document (as a file) and output to memory.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
| Name | Description |
|---|---|
| InsertCertToBytes(Byte[], String) | Insert certificate information into an XML document (as a byte array) and output to memory. |
| InsertCertToBytes(String, String) | Insert certificate information into an XML document (as a file) and output to memory. |
public static byte[] InsertCertToBytes(
string xmlFile,
string certFile
)Name of input XML file to be processed (or a string containing XML data)
X.509 certificate file
Byte[]
XML data as a byte array.
(file) –> (bytes)
// Pass input XML data as a string
string xmlStr = File.ReadAllText("cfdv40-ejemplo-nocertnum.xml");
string cerStr = Sat.GetCertAsString("emisor.cer");
byte[] b = Sat.InsertCertToBytes(xmlStr, cerStr);
Console.WriteLine(System.Text.Encoding.UTF8.GetString(b));
// <cfdi:Comprobante
// ...
// NoCertificado="30001000000300023708" Sello="" Certificado="MIIF+TCCA+GgAwIBAgIU ...Form message digest of piped string (cadena) from an XML file.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string MakeDigestFromXml(
string xmlFile
)Name of input XML file to be processed (or a string containing XML data)
String
Message digest in hex format or empty string on error
Console.WriteLine(Sat.MakeDigestFromXml("cfdv40-ejemplo-signed-tfd.xml"));
// 0ff1274e51fbb090489588d832bb1b5b36543302decbb0a5490839b8c99e8755Create the piped string (cadena) from an XML file.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string MakePipeStringFromXml(
string xmlFile
)Name of input XML file to be processed (or a string containing XML data)
String
Piped string.
string s = Sat.MakePipeStringFromXml("cfdv40-ejemplo.xml");
Console.WriteLine(s);
// ||3.3|A|123ABC|2017-12-04T01:23:59|02|...[cut]...||Create signature as a base64 string from data in an XML file ready to
be inserted as a sello node.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string MakeSignatureFromXml(
string xmlFile,
string keyFile,
string password = ""
)Name of input XML file to be processed (or a string containing XML data)
Name of private key file
Password
String
Signature in base64 format or empty string on error
string s = Sat.MakeSignatureFromXml("cfdv40-ejemplo.xml", "emisor.key", "12345678a");
Console.WriteLine(s);
// JQJd6rbiMZj1tZVb1Ta8l88bE7pTDm/aAl ...Save keyfile with a new password.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static int NewKeyFile(
string newFile,
string newPassword,
string keyFile,
string keyPassword,
KeyFormat format
)Name of new output file to be created.
Password for new key file.
Name of input key file (or a string containing the key in PEM form).
Password for existing key file.
Format to save file [default = DER binary].
Int32
Zero (0) if output file is successfully created, or a negative error code.
string password = "12345678a";
string newpassword = "password123";
int n = Sat.NewKeyFile("emisor_new.pem", newpassword, "emisor.key", password, KeyFormat.PEM);
Debug.Assert(n == 0, "Sat.NewKeyFile failed");
Console.WriteLine(File.ReadAllText("emisor_new.pem"));
// -----BEGIN ENCRYPTED PRIVATE KEY-----
// MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIn2sl+Cj3VtgCAggA ...
// -----END ENCRYPTED PRIVATE KEY-----Query an X.509 certificate.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string QueryCert(
string fileName,
Query query
)X.509 certificate file or XML file with certificado
node
Query
String
Result of query or an empty string on error
Modify the string returned when GetXmlAttribute(String, String, String) fails to find a match.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static void SetXmlNoMatch(
string value
)New string value.
// Show default NoMatch string
Console.WriteLine(Sat.XmlNoMatch());
// !NO MATCH!
string fname = "cfdv40-ejemplo-signed-tfd.xml";
// Look for element that isn't there
Console.WriteLine(Sat.GetXmlAttribute(fname, "", "/Comprobante/notthere"));
// !NO MATCH!
// Set a new NoMatch string
Sat.SetXmlNoMatch("##No coinciden##");
Console.WriteLine(Sat.GetXmlAttribute(fname, "", "/Comprobante/notthere"));
// ##No coinciden##Sat Class
FirmaSAT Namespace
XmlNoMatch()
Sign an XML file
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static int SignXml(
string newFile,
string baseFile,
string keyFile,
string password = "",
string certFile = "",
SignOptions signOpts = SignOptions.Default
)Name of new file to be created
Name of base XML file to be signed (or a string containing XML data)
Name of private key file
Password
Name of X.509 certificate file to be included in output XML (optional)
Options for output format (optional)
Int32
0 if successful or non-zero error code
if failed
This will create an output XML document copied from the input with
the Sello node overwritten by a new signature value. Any
existing file called newFile will be overwritten without
warning; however, the input and output files can be the same.
If a certificate file szCertFile is specified then the
Certificado and NoCertificado nodes will be
overwritten in the output file with the values in the certificate file.
If a certificate file is not specified then the Certificado
value in the XML will be used. A version 4 CFDi document to be signed
must use the “cfdi:” namespace prefix. For CFD v4 the
NoCertificado attribute in the input must be set to the
correct certificate serial number before signing. In a Retenciones
document you must set the CertNum attribute before signing.
In a ControlesVolumetricos document you must set both the
noCertificado and certificado attributes
before signing.
int n = Sat.SignXml("cfdv40-signed_new.xml", "cfdv40-ejemplo.xml", "emisor.key", "12345678a", "emisor.cer");Note: This API is now obsolete. Sign an XML file with extended options [deprecated].
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
[ObsoleteAttribute("Use Sat.SignXml with optional SignOptions parameter")]
public static int SignXmlEx(
string newFile,
string xmlFile,
string keyFile,
string password,
string certFile,
SignOptions signOpts
)Name of new file to be created
Name of base XML file to be signed
Name of private key file
Password for private key file
(optional) name of X.509 certificate file to be included in output XML
Options for output format
Int32
0 if successful or non-zero error code
if failed
See the remarks in SignXml(String, String, String, String, String, SignOptions)
int n = Sat.SignXmlEx(newname, fname, keyfile, password, certfile, SignOptions.BigFile);Sign XML data writing output to a byte array.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
| Name | Description |
|---|---|
| SignXmlToBytes(Byte[], String, String, String, SignOptions) | Sign XML data writing output to a byte array. |
| SignXmlToBytes(String, String, String, String, SignOptions) | Sign XML file writing output to a byte array. |
public static byte[] SignXmlToBytes(
byte[] xmlData,
string keyFile,
string password = "",
string certFile = "",
SignOptions signOpts = SignOptions.Default
)Byte array containing XML data
Name of private key file (or string containing key data in PEM format)
Password for key file
(optional) name of X.509 certificate file to be included in output XML (or string containing certificate data in base64 or PEM format)
Options for output format
Byte[]
Signed XML data in a byte array
Output XML is always UTF-8 encoded
string password = "12345678a";
string keyStr = Sat.GetKeyAsString("emisor.key", password, KeyOption.EncryptedPEM);
string cerStr = Sat.GetCertAsString("emisor.cer");
byte[] xmlArr = File.ReadAllBytes("cfdv40-ejemplo.xml");
byte[] xmlArrSigned = Sat.SignXmlToBytes(xmlArr, keyStr, password, cerStr, 0);
Console.WriteLine(System.Text.Encoding.UTF8.GetString(xmlArrSigned));
// <?xml version="1.0" encoding="UTF-8"?>
// <cfdi:Comprobante xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cfdi="http://www.sat.gob.mx/cfd/3" ...Sign XML file writing output to a byte array.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
| Name | Description |
|---|---|
| SignXmlToBytes(Byte[], String, String, String, SignOptions) | Sign XML data writing output to a byte array. |
| SignXmlToBytes(String, String, String, String, SignOptions) | Sign XML file writing output to a byte array. |
public static byte[] SignXmlToBytes(
string xmlFile,
string keyFile,
string password = "",
string certFile = "",
SignOptions signOpts = SignOptions.Default
)Name of base XML file to be signed
Name of private key file (or string containing key data in PEM format)
Password for key file
(optional) name of X.509 certificate file to be included in output XML (or string containing certificate data in base64 or PEM format)
Options for output format
Byte[]
Signed XML data in a byte array
Output XML is always UTF-8 encoded
byte[] b = Sat.SignXmlToBytes("cfdv40-ejemplo.xml", "emisor.key", "12345678a", "emisor.cer", SignOptions.Default);
Console.WriteLine(System.Text.Encoding.UTF8.GetString(b));
// <?xml version="1.0" encoding="UTF-8"?>
// <cfdi:Comprobante xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cfdi="http://www.sat.gob.mx/cfd/3" ...Generate a Universally Unique IDentifier (UUID) compliant with RFC 4122.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string Uuid()String
UUID string of exactly 36 characters
The output value will be different each time.
Console.WriteLine(Sat.Uuid());
// 343c6b13-4f69-4d2a-97e6-64cb770c7677Validate an XML file against SAT specifications.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static int ValidateXml(
string xmlFile,
XmlOption xmlOpt = XmlOption.Default
)Name of input XML file to be processed (or a string containing XML data)
Option for strict or loose XML restrictions (optional, default=Strict)
Int32
0 if successful or non-zero error
code
This just validates the XML structure, not the signature.
int n = Sat.ValidateXml("cfdv40-ejemplo.xml");
Console.WriteLine("Sat.ValidateXml returns {0}", n);
// Sat.ValidateXml returns 0
int n = Sat.ValidateXml("cfdv40-iedu-badcurp.xml");
Console.WriteLine("Sat.ValidateXml returns {0}", n);
// Sat.ValidateXml returns -28
Console.WriteLine(General.ErrorLookup(n));
// XML restriction is violated/XML restriccion es violada (XML_FACET_ERROR)
Console.WriteLine(General.LastError());
// Bad attribute/atributo mal [iedu:instEducativas/@CURP] (line 30):
// 'JUAN01010101GTOHMD0' is too long/es demasiado largo, maximum length/longitud maxima=18// Input has valid XML form but an invalid facet error against SAT specifications
// Using the "Loose" option validates that the XML form is still correct.
int n = Sat.ValidateXml("cfdv40-iedu-badcurp.xml", XmlOption.Loose);
Console.WriteLine("Sat.ValidateXml(Loose) returns {0}", n);
// Sat.ValidateXml(Loose) returns 0Verify the signature (sello) in an XML file.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static int VerifySignature(
string xmlFile,
string certFile = ""
)Name of input XML file to be processed (or a string containing XML data)
X.509 certificate file (optional)
Int32
Zero if signature is verified or nonzero error code if failed
If no certFile is specified, the public key is obtained
from the certificado node in the XML file.
Console.WriteLine(Sat.VerifySignature("cfdv40-ejemplo-signed.xml"));
// 0
Console.WriteLine(Sat.VerifySignature("cfdv40-badsig.xml"));
// -15
Console.WriteLine(General.ErrorLookup(-15));
// Decryption error/De error de descifrado (DECRYPT_ERROR)Error message returned when GetXmlAttribute(String, String, String) fails to find a match
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string XmlNoMatch()String
Error message (default = "!NO MATCH!")
Use to test for existence of an element. The message can be changed using SetXmlNoMatch(String).
Console.WriteLine(Sat.XmlNoMatch());
// !NO MATCH!Sat Class
FirmaSAT Namespace
SetXmlNoMatch(String)
Find version number of Comprobante element or ID number for other document types.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static int XmlReceiptVersion(
string xmlFile
)Name of XML file
Int32
Version number or ID number, or a negative error code. 40 = Comprobante document
with Version=“4.0”33 = Comprobante document with version=“3.3”1010/1020
= Retenciones document with Version=“1.0”/“2.0”2011/2013 =
CatalogoCuentas document with Version=“1.1”/“1.3”2111/2113 =
BalanzaComprobacion document with Version=“1.1”/“1.3”2211/2213 =
PolizasPeriodo document with Version=“1.1”/“1.3”2312/2313 =
AuxiliarFolios document with Version=“1.2”/“1.3”2411/2413 = AuxiliarCtas
document with Version=“1.1”/“1.3”2511 = SelloDigitalContElec document
with Version=“1.1”4011 = ControlesVolumetricos document with
Version=“1.1”
Console.WriteLine(Sat.XmlReceiptVersion("cfdv40-ejemplo.xml")); // 40Methods for Timbre Fiscal Digital (TFD).
System.Object
FirmaSAT.Tfd
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public class TfdThe Tfd type exposes the following members.
| Name | Description |
|---|---|
| AddSignedTfd | Add a signed Timbre Fiscal Digital (TFD) element to a CFDI document. |
| ExtractDigestFromSignature | Extract message digest from the selloSAT node in Timbre Fiscal Digital of CFDI document. |
| MakeDigestFromXml | Form message digest of cadena original del Timbre Fiscal Digital del SAT (TFD piped string) from CFDI XML file. |
| MakePipeStringFromXml | Create the cadena original del Timbre Fiscal Digital del SAT (TFD piped string) from CFDI XML file. |
| MakeSignatureFromXml | Create the selloSAT signature as a base64 string from
TFD data in CFDI XML document. |
| VerifySignature | Verify the selloSAT signature in CFDI XML document. |
Add a signed Timbre Fiscal Digital (TFD) element to a CFDI document.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static int AddSignedTfd(
string newFile,
string inputFile,
string keyFile,
string password,
string certFile
)Name of new file to be created
Name of existing CFDI file
Name of PAC’s private key file
Password for private key
Name of PAC’s X.509 certificate that matches the keyFile
Int32
Zero (0) if successful or non-zero error
code if failed
The inputFile must be a version 4.0/3.3 CFDi document already signed
with a sello field and no existing TFD element. The TFD
will be timestamped using the system clock and a fresh UUID will be
generated. No other XML processing is carried out except inserting the
TFD element.
int n = Tfd.AddSignedTfd(newname, fname, keyfile, password, certfile);
Console.WriteLine("Tfd.AddSignedTfd returns {0}", n); // 0
string s = Sat.GetXmlAttribute("cfdv40-ejemplo_signed.xml", "SelloSAT", "TimbreFiscalDigital");
// SelloSat=Qncw19SZ0w/uxkwCYkf/7V3DF3j28Jp1XyNVyqiyOreq0S ...Extract message digest from the selloSAT node in Timbre Fiscal Digital of CFDI document.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string ExtractDigestFromSignature(
string xmlFile,
string certFile
)Name of input XML file to be processed (or a string containing XML data)
X.509 certificate file of PAC who signed the TFD (required)
String
Message digest in hex format or empty string on error
Form message digest of cadena original del Timbre Fiscal Digital del SAT (TFD piped string) from CFDI XML file.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string MakeDigestFromXml(
string xmlFile
)Name of input XML file to be processed (or a string containing XML data)
String
Message digest in hex format or empty string on error
Create the cadena original del Timbre Fiscal Digital del SAT (TFD piped string) from CFDI XML file.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string MakePipeStringFromXml(
string xmlFile
)Name of input XML file to be processed (or a string containing XML data)
String
Piped string in UTF-8 encoding
Create the selloSAT signature as a base64 string from
TFD data in CFDI XML document.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string MakeSignatureFromXml(
string xmlFile,
string keyFile,
string password
)Name of input XML file to be processed (or a string containing XML data)
Name of private key file
Password
String
Signature in base64 format or empty string on error
Assumes you are a PAC with a valid SAT signing key.
Verify the selloSAT signature in CFDI XML document.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static int VerifySignature(
string xmlFile,
string certFile
)Name of input XML file to be processed (or a string containing XML data)
X.509 certificate file of PAC who signed the TFD (required)
Int32
0 if signature is verified or non-zero error code if failed
Format for saved key files.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public enum KeyFormat| Member name | Description |
|---|---|
| Default | Default = Binary |
| Binary | Binary DER-encoded |
| PEM | PEM Format |
Options for key output in Sat.GetKeyAsString().
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public enum KeyOption| Member name | Description |
|---|---|
| Default | Default (unencrypted base64 string). |
| UnencryptedBase64 | Key as unencrypted base64 string suitable for Cancelacion element. |
| EncryptedPEM | Key as encrypted private key in PEM format suitable for input as a
keyFile parameter. |
Get private key data as a base64 string suitable for a
llaveCertificado element in a Cancelacion XML
document
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static string GetKeyAsString(
string fileName,
string password,
KeyOption keyOpt = KeyOption.Default
)Encrypted private key file
Password for encrypted private key
Output format (optional, default=UnencryptedBase64)
String
Private key data as a string or empty string on error
CAUTION: the unencrypted default option reveals your private key in unsecured form. Use with care!
Console.WriteLine(Sat.GetKeyAsString("emisor.key", "12345678a"));
// PFJTQUtleVZhbHVlPjxNb2R1bHVzP ... WYWx1ZT4=Console.WriteLine(Sat.GetKeyAsString("emisor.key", "12345678a", KeyOption.EncryptedPEM));
// -----BEGIN ENCRYPTED PRIVATE KEY-----
// MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIAgEAAoIBAQACAggA
// ... rbw=
// -----END ENCRYPTED PRIVATE KEY-----Options for PKCS12 (PFX) output in Sat.WritePfxFile().
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public enum PfxFormat| Member name | Description |
|---|---|
| Default | Default (plain base64 suitable for Cancelacion element). |
| Base64 | PFX data as plain base64. |
| PEM | PKCS12 PEM textual form = same as Base64 but with PEM encapsulation
-----BEGIN PKCS12-----...-----END PKCS12----- |
| Binary | Binary DER form. |
Create PFX (PKCS-12) file in PEM format suitable for a Cancelación.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public static int WritePfxFile(
string pfxFile,
string pfxPassword,
string keyFile,
string keyPassword,
string certFile,
PfxFormat pfxFormat = PfxFormat.Default
)Name of output PFX file to be created
Password to open new PFX file
Name of encrypted key file
Password for encrypted key file
Name of X.509 certificate file
Output format for PFX file (optional, default=plain base64)
Int32
Zero (0) if output file is successfully created, or a negative error code.
string password = "12345678a";
string newpassword = "clavedesalida";
int n = Sat.WritePfxFile("archivo_new-pfx.txt", newpassword, "emisor.key", password, "emisor.cer");
Debug.Assert(n == 0, "Sat.WritePfxFile failed");
Console.WriteLine(File.ReadAllText("archivo_new-pfx.txt"));
// MIIMOQIBAzCCC/8GCSqGSIb3DQEHAaCCC/AEggvsMIIL6DCCBp8GCSqGSIb3DQEH ...Options for certificate query.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public enum Query| Member name | Description |
|---|---|
| notAfter | Get certificate expiry date. |
| notBefore | Get certificate start date. |
| organizationName | Get organization name of issuer. Expecting “Servicio de Administración Tributaria” if issued by SAT |
| companyName | Get organization name of subject. This should be your company name. |
| rfc | Get RFC of subject. Expecting 12 or 13 characters if issued by SAT. |
| serialNumber | Get decoded serial number. Expecting 20 decimal digits. |
| sigAlg | Get algorithm used to sign certificate (e.g. “sha256WithRSAEncryption”). |
| keySize | Get size in bits of certificate’s public key (e.g. “2048”). |
Options for signing XML.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
[FlagsAttribute]
public enum SignOptions| Member name | Description |
|---|---|
| Default | Default (add BOM, empty elements in form
<foo></foo>). |
| NoBOM | Do not add byte-order mark (BOM) to file. |
| OverrideReqd | Override strict checks for required nodes (advanced users). |
| UseEmptyElements | Output empty elements in empty-element tag form
<foo /> (default is start-end tag pair form
<foo></foo>). |
| BigFile | Speed up the processing of large files. |
Options for XML validation.
Namespace: FirmaSAT
Assembly: diFirmaSatNet (in diFirmaSatNet.dll) Version:
10.70.0.36515 (10.70.0.0)
public enum XmlOption| Member name | Description |
|---|---|
| Default | Default value (strict) |
| Strict | Enforce stricter XML restrictions (default in v5.0 and above). |
| Loose | Use looser restrictions on data types (default before v5.0). |
Created: 2025-10-20 20:18:00
Copyright (C) 2025 D.I. Management Services Pty Ltd t/a CryptoSys https://cryptosys.net