FirmaSAT
FirmaSAT
is a add-on utility for users of the
CryptoSys PKI Toolkit which enables you to create and read
digital receipts (Comprobantes Fiscal Digital)
as specified by the Servicio de Administración Tributaria* (SAT) in Mexico.
FirmaSAT
is a command-line program that works with Version 2.0 SAT XML files [REF1].
You can run it from the command-line, or call it from another program (e.g. from ColdFusion).
There is a .NET class library for VB.NET and C# programmers,
an API for C and C++ programmers,
and
an interface for VB6/VBA programmers.
For other related information, see SAT Mexico and the CryptoSys PKI Toolkit.
FirmaSAT enables the user to:
Version 2.0 of FirmaSAT:
Complemento field:
see Complemento Detallista extension for retailersdiFirmaSAT2.dll from diFirmaSAT.dll in version 1 to avoid DLL namespace clashes.CERTSTRING = get the Certificate data as a base64 string DATENOTAFTER = get the expiry Date of the certificate. EXTRACTDIGEST = Extract the digest from the signature. FORMDIGEST = Form the digest of the pipestring. NUMBERCERT = get the certificate serial Number.
Download a free Trial Edition of FirmaSAT now. Use either
Unzip the zip file and run the setup.exe program inside it, or download the exe program directly and run it.
The Trial Edition is fully-functional. You need administrator privileges to install the program. Please read the licence conditions for the Trial Edition. The latest version 2.0.0 was released on 13 January 2010. The trial period is 60 days from the date first installed on your system. Requires the CryptoSys PKI Toolkit.
You can purchase a licensed version here. Existing licence holders can download the latest Developer Edition here.
(Alternatively, open a command-line window (MS-DOS window) and change directory by typing
CD %APPDATA%\FirmaSAT.)
FirmaSAT LIBINFO. If correctly installed, the output should be similar to:
>FirmaSAT LIBINFO FirmaSat Version 2.0.0 last updated Jan 13 2010 13:29:08. diFirmaSat DLL: Version: 200 Module: C:\WINDOWS\system32\diFirmaSAT2.dll Compiled: Jan 13 2010 13:28:03 Licence: D CryptoSys PKI DLL: Version: 340 Module: C:\WINDOWS\system32\diCrPKI.dll Compiled: Dec 19 2009 21:54:59
the application has failed to start because diCrPKI.dll/diFirmaSat2.dll was not foundthen the installation is not correct.
'FirmaSAT' is not recognized as an internal or external command, operable program or batch file.then you need to set the path to the program which is in the
%ProgramFiles%\FirmaSAT directory
(or %ProgramFiles(x86)%\FirmaSAT in 64-bit Windows).
SET PATH=%ProgramFiles%\FirmaSAT;%PATH%See the batch file
SetupForFirmaSAT.bat provided.
Usage: FirmaSat ACTION [OPTIONS] [-i] infile [[-o] outfile] ACTION (one of): ATTRIBUTE = extract a given Attribute from XML file. CERTSTRING = get the Certificate data as a base64 string. DATENOTAFTER = get the expiry Date of the certificate. EXTRACTDIGEST = Extract the digest from the signature. FORMDIGEST = Form the digest of the pipestring. HELP = display this Help. LIBINFO = display DLL Library details. MAKESIG = Make signature from XML file. NUMBERCERT = get the certificate serial Number. PIPESTRING = make Pipestring (cadena) from XML file. SIGNXML = create the Signature and set `sello' field in XML file. VERIFYSIG = Verify the signature in XML file. XMLOK = validate XML file. OPTIONS: -k <keyfile> (required for SIGNXML) -p <password> (required for SIGNXML) -c <certfile> (optional X.509 certificate file for VERIFYSIG/SIGNXML) -a <attribute-name> (required for ATTRIBUTE action) -e <element-name> (ditto) -s <statusfile> (default=none; for stdout use ``-s @'') -t <tracking-info> (optional info for the status file) -w display help/errors in Windows console font (default=Latin-1) -d show debug info; -dd show more For help type ``FirmaSat HELP'' (en espanol, ``FirmaSat AYUDA -w'') FirmaSat Version 2.0.0 last updated Jan 13 2010 13:29:08.
All action names and options are case-insensitive. To see the latest syntax, type ``FirmaSAT HELP''. En español, type ``FirmaSAT AYUDA -w''. The -w option causes the accented characters (e.g. ñ, é) to appear properly in the Windows console (at least for the help messages - UTF-8 characters in XML output will still appear "funny").
As an option, you can specify the name of a tracking file (using the -s option) which will contain the results of the operation. This can be used for tracking automated procedures.
All actions (except HELP and LIBINFO) require an input file to be specified. The input file must be a valid XML file encoded in UTF-8. Only SAT version 2.0 format is supported.
To create the piped-string using PIPESTRING or to make the signature using the MAKESIG action, only the fields required for the piped string need be present in the XML file.
To validate the XML file using XMLOK, all required fields must exist.
To verify the signature using VERIFYSIG, the `sello' field must exist and either the 'certificado' field exists in the XML file or the X.509 certificate file is specified in the command line using the -c option. As of Version 2, the certificate specified with the -c option will take priority over any `certificado' field.
To sign the XML file using the SIGNXML action, then `sello' must exist as an empty field (i.e. sello="").
The output XML file will have the `sello' field completed.
A new output XML file is created by this action. The input file is not touched. The input and output files can be the same.
If an X.509 certificate is specified using the -c option, then the `certificado' and `noCertificado' fields
will be completed provided empty fields are specified in the input XML file.
For example, your XML file for input should include the following:
<?xml version="1.0" encoding="utf-8"?> <Comprobante ... version="2.0" noCertificado="" sello="" certificado="">
Version 2.0 includes support for the Complemento Detallista extension for retailers as per
[REF2]. There is an example XML file in the distribution (detallista_base.xml)
that can be signed with the test keys (detallista-new-signed.xml) and the result passes the SAT validation.
We have had only limited examples of this extension to test.
We shall not comment about the awful verbosity that this new extension adds, nor the inconsistency in mixing element content
and attributes, nor the inconsistent capitalization of field names. No, we shall not comment.
Here is a sample of the detallista part. Only nine fields in this extra section are used in the piped string. If you want to send us further examples of detallista XML files, please do.
<Complemento>
<detallista:detallista type="SimpleInvoiceType"
documentStructureVersion="AMC8.1"
documentStatus="ORIGINAL"
contentVersion="1.3.1">
<detallista:requestForPaymentIdentification>
<detallista:entityType>INVOICE</detallista:entityType>
</detallista:requestForPaymentIdentification>
...etc, etc...
</detallista:detallista>
</Complemento>
These examples use the sample test files provided in FirmaSATtestfiles.zip.
Note that the test certificates and keys used (from the SAT site) are due to expire in August 2010.
FirmaSAT XMLOK Muestra_v2_base2.xml
will check that the input file is validly formed XML. The output in this case should be
OK
If the XML file is not validly formed, the output would be like:
Error code -27: Invalid XML format: XML Validation Error: Required attribute 'formaDePago' missing for element 'Comprobante' (Line: 2 Col: 311); ... etc ...
Note that this is merely checking that the XML formatting of the input file is OK.
FirmaSAT PIPESTRING Muestra_v2_base2.xml
will output the "piped-string" to the console, e.g.
||2.0|A|1|2009-08-16T16:30:00|1|2009|ingreso| ...etc... |150.00|150|IVA|15.00|52.50||
Note that non-ASCII characters will not display properly on the console. It is better to output directly to a file:
FirmaSAT PIPESTRING Muestra_v2_base2.xml pipedstring.txt
FirmaSAT MAKESIG -k aaa010101aaa_csd_01.key -p a0123456789 Muestra_v2_base2.xml
will create the signature `sello' from the input XML file using the private key and password provided. The output should be
UlUSwGNEicfigV6i4RhTy0eb2RYWFYyFatJFcM/u5Wlkb5XRxXiCizTGw5Yxz9oZNk8msAgO4C5Gevjh +S2TJPZueYhaQeZlo6k0rE3CQexkOGVRpHkvAoAgOM5kGKzYe24DKZbTgjNL+ai+tbhEHmRAFcpv2rDp ehbL3w6BnYU=
FirmaSAT SIGNXML -s @ -k aaa010101aaa_csd_01.key -p a0123456789 ¶ -c aaa010101aaa_csd_01.cer -i Muestra_v2_base2.xml -o Muestra_v2_signed2-new.xml
will create a new signed XML file `Muestra_v2_signed2-new.xml' from the input XML file `Muestra_v2_base2.xml'. It will sign using the private key in `aaa010101aaa_csd_01.key' and will add the `certificado' details from the X.509 certificate file `aaa010101aaa_csd_01.cer'. (Note that the above line is split for display purposes - it should be entered in one continuous line.) In version 2 it is now an error if the certificate and key do not match. See also the caution below about hard-coding passwords.
FirmaSAT VERIFYSIG Muestra_v2_signed2.xml
will verify the signature in the signed XML file. In this case it will use the `certificado' details in the XML file itself.
OK
FirmaSAT VERIFYSIG Muestra_v2_signed2-nocert.xml
will try to verify the signature in the signed XML file. In this case, there is no `certificado' field in the XML file and an error will result:
Error code -8: The data is invalid/Los datos no es válida: Invalid X.509 certificate
FirmaSAT VERIFYSIG -c aaa010101aaa_CSD_01.cer Muestra_v2_signed2-nocert.xml
will use the certificate `aaa010101aaa_CSD_01.cer' to verify the signature in the XML file. This should produce
OK
FirmaSAT ATTRIBUTE -d -a sello -e Comprobante -i Muestra_v2_signed2.xml
will extract the attribute `sello' from the element `Comprobante' in the input XML file. The output should look like this:
Attribute=[sello] Element=[Comprobante] UlUSwGNEicfigV6i4RhTy0eb2RYWFYyFatJFcM/u5Wlkb5XRxXiCizTGw5Yxz9oZNk8msAgO4C5Gevjh +S2TJPZueYhaQeZlo6k0rE3CQexkOGVRpHkvAoAgOM5kGKzYe24DKZbTgjNL+ai+tbhEHmRAFcpv2rDp ehbL3w6BnYU=
FirmaSAT NUMBERCERT Muestra_v2_signed2.xml
will extract the serial number from the X.509 embedded in the `certificado' field of the XML file The output should look like this:
10001200000000022517
FirmaSAT DATENOTAFTER aaa010101aaa_CSD_01.cer
will extract the expiry date from the X.509 certificate file directly.
2010-08-21T15:22:08Z
FirmaSAT CERTSTRING aaa010101aaa_CSD_01.cer
will form the certificate string from the X.509 certificate file in the required base64 format to insert in the `certificado` field. The output should look like this:
MIIDhDCCAmygAwIBAgIUMTAwMDEyMDAwMDAwMDAwMjI1MTcwDQYJKoZIhvcNAQEFBQAwgcMxGTAXBgNV BAcTEENpdWRhZCBkZSBNZXhpY28xFTATBgNVBAgTDE1leGljbywgRC5GLjELMAkGA1UEBhMCTVgxGjAY ... tfROdG+1qYeA1q/is04O4AXNmMByGp7ZnvGNrO9LDBvs3eKN4ZYcQyjxFEbr1X/xUqHCRF1VEkkC5jJQ 1ktC4g==
FirmaSAT FORMDIGEST Muestra_v2_signed2.xml
will form the piped string from the XML file and then compute its message digest in hex form. The output should look like this:
4cd8ed248d7a02314c50778a37d1522d
This should match both the digest extracted with EXTRACTDIGEST (see below) and the "cadena original" displayed by the S.A.T. Validador. If it does not there is a problem - see Troubleshooting.
FirmaSAT EXTRACTDIGEST Muestra_v2_signed2.xml
will extract the message digest in hex form from the signature field in the XML file. It will use the embedded certificate in the XML file to decrypt the signature. The output should look like this:
4CD8ED248D7A02314C50778A37D1522D
FirmaSAT EXTRACTDIGEST -c aaa010101aaa_CSD_01.cer Muestra_v2_signed2-nocert.xml
will extract the message digest in hex form from the signature field in the XML file. In this case, as there is no embedded certificate, it requires the name of the X.509 certificate file. The output should look like this:
4CD8ED248D7A02314C50778A37D1522D
FirmaSAT HELP
will display the usage syntax.
FirmaSAT AYUDA -w
will display the usage syntax in Spanish (the -w option makes sure it displays properly on the Windows console).
FirmaSAT LIBINFO
will display details about the program and the libraries it depends on.
CAUTION: You should never hard-code the password for your production private key anywhere. You should always require the user to enter it each time. Here is an example of a simple batch file that expects the password to be typed in as the first parameter.
@echo off if "%1"=="" goto NOPASSWORD set mypwd=%1 FirmaSAT SIGNXML -s @ -k aaa010101aaa_csd_01.key -p %mypwd% ¶ -c aaa010101aaa_csd_01.cer -i Muestra_v2_base2.xml -o Muestra_v2_signed2-new.xml set mypwd= goto DONE :NOPASSWORD echo ERROR: no password :DONE
Use a text editor to create a batch file called, say, SignXMLTest.bat with the above text in it
(the line beginning "FirmaSAT" with the ¶ character should be entered as one line).
Then type "SignXMLTest a0123456789" on the command line.
>SignXMLTest a0123456789 STATUS: 0 ERRORDESCRIPTION: OK DATETIMECREATED: Thu Jan 14 11:48:13 2010
Obviously, you could adapt this batch file to cope with different files and certificates.
To call from a C or C++ program, use
#include diFirmaSAT2.h
in your source code
and link with the diFirmaSAT2.lib library.
For more details on the core functions you can call from C or C++, see the file diFirmaSAT2.h.
Make sure you read the note near the bottom about Functions that provide output in `szOut`.
2010-03-12:
Here is some test code written in C
(zipped, 13 kB). It includes the test files.
The .NET interface allows programmers to call functions in FirmaSAT directly
from C# and VB.NET (VB2005/8/x) programs. The core library diFirmaSAT2.dll
must be installed on your system (as well as CryptoSys PKI).
The .NET interface requires you to add a reference to the .NET Class Library file
diFirmaSatNet.dll
(the other DLLs are found automatically provided they are in
the Library Search Path).
Full details of the .NET methods are available in the file FirmaSat.NET.chm (zipped, 95 kB).
You can browse this help on-line.
diFirmaSatNet.dll.using FirmaSAT;or (for VB.NET)
Imports FirmaSATto your code.
using FirmaSAT; int n = General.Version(); Console.WriteLine("Version = {0}", n);or in VB.NET
Imports FirmaSAT Dim n As Integer n = General.Version() Console.WriteLine("Version = {0}", n)
See the example test code provided in the distribution download:
TestFirmaSat.cs for C# and TestFirmaSat.vb for VB.NET.
The VB6/VBA interface provides access to the FirmaSAT functions from a VB6 project or from a Microsoft Office VBA application like Excel or Access. This interface is new (2010-03-11) and is not included in the 2.0.0 distribution.
Download a sample VB6 project (15 kB).
To use, include the file basFirmaSAT.bas in your project and call the functions. There are wrapper functions to handle the messy stuff.
For example
Debug.Print ("Interrogate the core diFirmaSat DLL:")
n = SAT_Version()
Debug.Print "Version=" & n
ch = Chr(SAT_LicenceType())
Debug.Print "LicenceType=" & ch
Debug.Print "ModuleName=" & satModuleName()
Debug.Print "CompileTime=" & satCompileTime()
The download above includes a set of tests almost identical to the tests for the .NET interface. Note that the project expects the test files
to be in the C:\Test\FirmaSAT directory. You can easily change this to suit your system (see the code in Form1.frm).
FirmaSAT XMLOK myfile.xmlIf this fails, your XML is badly-formed.
FirmaSAT FORMDIGEST myfile.xml
4cd8ed248d7a02314c50778a37d1522d
FirmaSAT EXTRACTDIGEST myfile.xml
4CD8ED248D7A02314C50778A37D1522D
If this test fails, your embedded signature (sello field) is corrupted or the certificate (certificado field) is wrong.
El sello del comprobante es válido: Comprobante C:\somepath\myfile.xml leido exitosamente ... Digestión MD5 de cadena como HEX: 4cd8ed248d7a02314c50778a37d1522d
The MD5 digest results for tests 2, 3 and 4 should all be the same (it does not matter that the letters are in upper-case [A-F] or lower-case [a-f]). If test 1 is OK, and the results of 2, 3 and 4 are the same, and the XML file still fails SAT validation, please send the file to us for further investigation.
Tests 2 and 3 are equivalent to
FirmaSAT VERIFYSIG myfile.xml
but they provide extra clues as to where the problem may be if the VERIFYSIG action fails.
If tests 2 and 4 give the same result, but test 3 is different, then you are forming the piped-string correctly but somehow passing the wrong data to the signature function.
If tests 2 and 4 give different results, then there is an error in forming the piped-string. Remember, get just one character wrong in the piped-string and there will be an error.
If tests 2 and 3 give the same result, but test 4 is different then you are at least being internally consistent in creating the signature, but forming the piped-string incorrectly.
The XMLOK action validates the XML, meaning in this case merely that the XML is well formed
(i.e. it says nothing about the digital signature).
Validation of the XML is carried out using a DTD file plus some other checks.
This catches almost all problems but will not catch strict element typing issues (like using a letter in a field where a number is required).
The content of the Addenda element is ignored completely.
To carry out a more accurate validation using the XSD file provided by SAT, you will need to use a dedicated XML validation tool (try WMHelp.com's free XMLPad 3).
The "validation" carried out by the Validador site [SAT-VALIDADOR] is both a validation of the XML and a verification of the signature.
The program should work on all 32-bit versions of Windows 95/98/Me/NT4/2000/XP/2003/Vista/2008/W7.
The relevant executables are:
diFirmaSAT2.dllFirmaSAT.exediFirmaSatNet.dlldiCrPKI.dllDependencies: The program FirmaSAT.exe and the .NET class library diFirmaSatNet.dll
are both dependent on the library file
diFirmaSat2.dll, which,
in turn, is dependent on the core CryptoSys PKI DLL diCrPKI.dll.
None of these files need to be (or can be) registered with RegSvr32.
Contact: Send us an email.
For more information on the CryptoSys PKI Toolkit, go to <www.cryptosys.net/pki/>.
This page last updated 12 March 2010