Thursday, May 20, 2010

- Miosotis And Milena Velba

SF4 - Improving the MadCatz Arcade FightStick SE components Sanwa

If you are going to implement electronic invoicing in your application. NET, and you've decided on the format facturae, check that , to this day, the documentation and tools for working with this language is very limited.
  • If you do not know where to start, you're reading the lines you wanted.
  • Where do we start? Well, the "facturae" is a digitally signed XML file. So the first thing we do is generate the XML. As a good programmer, the first thing to do is read the official documentation, so in http://www.facturae.es/es-ES/Documentacion/EsquemaFormato/Paginas/Index.aspx
    find the table fields in PDF (keep her, you'll need) and the XSD schema format. Today there are 3 versions of facturae, 3.0, 3.1 and 3.2. The most current, 3.2, is still not widespread enough, so I recommend working (again, by day Today, May 2010) with version 3.1.
    The XSD schema that we find things much easier, because with him and xsd.exe tool we will generate a class whose instance we will generate the XML easily. To generate the *. cs need:

    Schema (XSD) downloaded from www.facturae.es (if the extension XML schema has change the extension to XSD) schema
    http://www.w3 .org / TR / XMLDSIG-core / XMLDSIG-core-schema.xsd

    With all this, we run the command give us the expected file:


    "C: \\ Program Files \\ Microsoft SDKs \\ Windows \\ v6.0A \\ bin \\ xsd" Facturaev31.xsd XMLDSIG-core-schema.xsd / c / n:
    FacturaElectronica

    / / Remove
    data file string file = "c: \\ temp \\ \\ pruebas.xml"
    XmlSerializer serializer = new XmlSerializer (typeof (Facturae));
    FileStream fs = new FileStream (file, FileMode.Create);
    serializer.Serialize (fs, invoices);
    fs.Close ();
    To fill the facturae object correctly, you should read the PDF containing the table fields, it tells you which fields are required, what they are and the format should be. And here is where we have a problem: there are some fields that have to have 2, 4 or 6 decimal places, but the type of data is a "Double", how do we specify that when generating the XML out exactly that number of decimal places ? Well, there are several solutions, mine is: will generate 3 classes, so that each class contains an attribute "Double." When serializing XML object of these classes, the numeric display with a fixed number of decimal places. 4 classes actually do: create a parent class to avoid repeating the attribute in the 3 classes: public abstract class
    DoubleFixedDecimalType {protected double value;
    public
    DoubleFixedDecimalType ()
    {value = 0;}
    public DoubleFixedDecimalType (double value) { this.value = value;}
     
    [System.Xml.Serialization.XmlText ()]
    public abstract string Value
    {
    get;
    set;
    }
    }

    public class DoubleTwoDecimalType : DoubleFixedDecimalType
    {
    public DoubleTwoDecimalType() : base() { }
    public DoubleTwoDecimalType(double value) : base(value) { }

    public static implicit operator double(DoubleTwoDecimalType o)
    {
    return o.value;
             } 

    public static implicit operator DoubleTwoDecimalType(double value)
    {
    return new DoubleTwoDecimalType(value);
    }

    [System.Xml.Serialization.XmlText()]
    public override string Value
    {
    get { return value.ToString("F2", System.Globalization.CultureInfo.InvariantCulture); }
    set { this.value = System.Convert.ToDouble(value); }
    }
    }

    public class DoubleFourDecimalType : DoubleFixedDecimalType
    {
    public DoubleFourDecimalType() : base() { }

    public DoubleFourDecimalType(double value) : base(value) { }

    public static implicit operator double(DoubleFourDecimalType o)
    {
    return o.value;
    }

    public static implicit operator DoubleFourDecimalType(double value)
    {
    return new DoubleFourDecimalType(value);
    }

    [System.Xml.Serialization.XmlText()]
    public override string Value
    {
    get { return value.ToString("F4", System.Globalization.CultureInfo.InvariantCulture); }
    set { this.value = System.Convert.ToDouble(value); }
    }
    }

    public class DoubleSixDecimalType : DoubleFixedDecimalType
    {
    public DoubleSixDecimalType() : base() { }

    public DoubleSixDecimalType(double value) : base(value) { }

    public static implicit operator double(DoubleSixDecimalType o)
    {
    return o.value;
    }

    public static implicit operator DoubleSixDecimalType(double value)
    {
    return new DoubleSixDecimalType(value);
    }

    [System.Xml.Serialization.XmlText()]
    public override string Value
    {
    get { return value.ToString("F6", System.Globalization.CultureInfo.InvariantCulture); }
    set { this.value = System.Convert.ToDouble(value); }
    }
    }

    As can be seen in the statements can be implicitly converted to an object "Double" to any instance of these classes, which makes us work because we can directly assign a numerical value.

    now is replace the *. cs file generated, the data type "Double" of the properties must have a fixed number of decimal places (see table fields) for one of these 3.

    To save you some work, here you have to download two files, generated xsd.exe and modified to get correct number of decimal places, for versions 3.1 and 3.2 facturae:
    Click here to download
    . At this

    point you can generate your facturae. You can check the validity of your XML Web
    the ministry of industry, tourism and trade
    . Your file must successfully pass validation and formatting, if you read it right the table fields and the amount of your bill is correct, you must also successfully pass the validation accounts. But we have one important thing, the firm.

    order to sign the XML, you need a digital certificate issued by a recognized certification authority. You order at the site of the factory
    national currency and stamps
    .

    Once you have the certificate (*. cer file formats, *. pfx ...) you can take the class
    X509Certificate2
    to load into memory and perform the signature. At this point there are several ways to load the certificate: from physical file, looking for a certificate installed on your computer, including a list of certificates and giving the user the ability to choose one ... In this example we will read a certificate installed on your computer, using asp.net. The user running the asp.net does not have sufficient permissions to read the private key (required to sign) if you import the certificate with the import wizard (import the private key in the warehouse of user you are logged .)

    To import a certificate and use it with asp.net, it we follow these steps (I repeat this is only necessary to use certificates with asp.net):



    Sign in as administrator

    Click on Start -> Run. Write mmc and hit Enter

    Click on File -> Add / Remove Snap-in, and click on "Add"

    Look in the "Certificates" and double click on it. Choose "Computer Account" and click Next

    Choose the option depending on where the certificate is (local or remote) Press

    end (see "Certificates" in the list of supplements added)
    Click "OK"
    Displays node "Certificates"
    Make Right-click the folder "Personal" and select "All Tasks -> Import"
    Click Next, find and select the certificate store
    Choose the "Personal" to save the certificate and end

    Now let's give permissions to the MachineKeys directory:


    Navigate to the directory where you store the keys:
      C: \\ Documents and Settings \\ All Users \\ Application Data \\ Microsoft \\ Crypto \\ RSA \\ MachineKeys
    1. NO
    2. sure you are using the Simple File Sharing mode (Tools -> Folder Options ... -> View tab, at the very end)
    3. Click the right mouse button on the MachineKeys directory. Choose "Properties" and then the Security tab
    4. *** Add the IUSR_ user and give permissions for all (total control)
    1. Once we already have the certificate stored, we use it to sign the generated XML. We will sign with XAdES . But how? Well, I have not found the right way. But I can tell you how to do so to see what it looks like the file, but only a trial. Why? Because what we do with a library licensed for use with factOffice (it is a plugin to work with electronic invoices from MsOffice) and not allowed to use it outside the plug.
    2. From factOffice Web find a link to that library ( Download ) we can include in our project, again, for testing only. BouncyCastle.Crypto.dll file also need to be found in the source code factOffice. Once imported these two libraries, sign the xml is as simple as this:
    3. XmlDocument doc = new XmlDocument (); doc.PreserveWhitespace = True; doc.Load ("c: \\ temp \\ \\ pruebas.xml"); / / Get certificate X509Store store = new X509Store (StoreName.My, StoreLocation.LocalMachine) store.Open (OpenFlags . ReadOnly);
    4. X509Certificate2Collection certCollection = store.Certificates.Find (X509FindType.FindBySubjectName, "NAME OF THE COMPANY", false);
    5. if (certCollection.Count == 1) { / / Signing XAdES-EPES ( basic format with minimal information) XadesSignature XadesSignature xadesSignature = new (); xadesSignature.XadesEpes (doc, "Entity Name", certCollection [0], "Name Application "); / / Save version signed
    6. doc.Save (" c: \\ temp \\ \\ pruebas_firmado.xml ");}
    / / Close store.Close certificate store ();
    Arrived At this point we have generated the XML file so that it would form validation, validation accounting and certificate validation.
    Soon I'll post how to perform the signature without using the library courtesy BackTrust so quietly signed to include XAdES in your application.
    Updated 20/05/2010 As promised (although this is only said when the promise) and here I offer you a way of signing electronic invoices XAdES using libraries that can be distributed safely in your application.
     What I have done is to use 
    IKVM.NET
    to convert the Java libraries offered by the ministry of industry, tourism and trade, dll libraries. Using jar2ikvmc

    can create a script for use with ikvmc, so that will take into account the dependencies of each jar file. Once converted
    the jar to dll, as it tried to make a signature XAdES-EPES, as explained in the examples of the ministry, but did not work because the program did not recognize the political signature. The program was trying to access a file to dynamically load different types of signature policies, then create an instance of the class that manages the policy. But this process did not work with libraries converted to dll. So I had to modify the Java source to let you specify the classes for the signing policy at compile time (not as dynamic, but works. Net!), Compile and create the jar files, and re-create the dll's . All information to use / modify / recompile the source is

    here.

    After that I managed to sign invoices in facturae with XAdES-EPES, from a certificate stored in a pfx file. To do this you also follow these steps:


    download the necessary files, click here to download

    .





    includes the following dll's in your project C # (find them in the previous download):





    commons-logging-1.1


    facturaE_adittional IKVM.
    OpenJDK.Core
    IKVM.OpenJDK.Security

    • IKVM.OpenJDK.Text
    IKVM.OpenJDK.Util
      IKVM.OpenJDK.XML.API
    IKVM.OpenJDK.XML.Parse
    • IKVM.Runtime
    • MITyCLibAPI-1.0.4-1.0.4 MITyCLibCert
    • MITyCLibPolicy-
    • 1.0.4-1.0.4 MITyCLibTrust
    • MITyCLibTSA-1.0.4-1.0.4 MITyCLibXADES
    • xmlsec-1.4.2-ADSI-1.0
    • Note: Some users have informed me that the dll
    • IKVM.OpenJDK.XML.Parse not automatically copied to the directory on the outcome of the solution. Take it into account if this is your case.
    • includes the following "using" in code: using java.security;
    • using java.io;
    • using java.util; using java.security.cert; using javax.xml.parsers;
    • using it. mityc.javasign.pkstore;
    • using es.mityc.javasign.pkstore.keystore; using es.mityc.javasign.trust; using es.mityc.javasign.xml.xades.policy;
    • using es.mityc.firmaJava. libreria.xades;
    • using es.mityc.javasign.xml.refs; using es.mityc.firmaJava.libreria.utilidades; using org.w3c.dom;
    • using sviudes.blogspot.com;
    • Use this code to sign bills: private
    • LoadXML Document (string path) {
    • DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true);
    • return dbf.newDocumentBuilder().parse(new BufferedInputStream(new FileInputStream(path)));
    } private X509Certificate LoadCertificate(string path, string password, out PrivateKey privateKey, out Provider provider) { X509Certificate certificate = null;
    provider = null;
      privateKey = null;
    • //Cargar certificado de fichero PFX
        KeyStore ks = KeyStore.getInstance("PKCS12"); 
      ks.load(new BufferedInputStream(new FileInputStream(path)), password.ToCharArray());
      IPKStoreManager storeManager = new KSStore(ks, new PassStoreKS (password));
      storeManager.getSignCertificates List certificates = ();

      / / If we find the certificate ...
      if (certificates.size () == 1) {

      certificate = (X509Certificate) certificates.get (0);

      / / Getting private key associated with the certificate PrivateKey = storeManager.getPrivateKey
      (certificate);

      / / Obtain the provider responsible for carrying out cryptographic provider = storeManager.getProvider
      (certificate);}
    •  return certificate; 
      } private void

      btnFirmar_Click (object sender, EventArgs e) {

      PrivateKey PrivateKey;
      Provider provider;
      LoadCertificate X509Certificate certificate = ("c: \\ temp \\ \\ certificado.pfx", "password", out PrivateKey, out provider);

      / / If we find the certificate ...
      if (certificate! = Null) {

      / / Policy signature (with the Java libraries, this is defined at runtime)
      es.mityc.javasign.trust.TrustExtendFactory.newInstance TrustFactory.instance = ();
      es.mityc.javasign.trust.MyPropsTruster.getInstance TrustFactory.truster = ();
      es.mityc.javasign.xml.xades.policy.facturae.Facturae31Manager PoliciesManager.POLICY_SIGN = new ();
      PoliciesManager.POLICY_VALIDATION = es.mityc.javasign.xml.xades.policy.facturae.Facturae31Manager new ();

      / / Create data to sign
      DataToSign DataToSign dataToSign = new ();
      dataToSign.setXadesFormat (EnumFormatoFirma.XAdES_BES) / / XAdES- EPES
      dataToSign.setEsquema (XAdESSchemas.XAdES_132)
      dataToSign.setPolicyKey (facturae31 ") / / No matter what I say here, the signature policy defined above
      dataToSign.setAddPolicy (true);
      dataToSign.setXMLEncoding ( "UTF-8");
      dataToSign.setEnveloped (true);
      dataToSign.addObject (new ObjectToSign (new AllXMLToSign (), "Document Description", null, "text / xml", null));
      dataToSign.setDocument (LoadXML ("c: \\ temp \\ \\ unsigned.xml"));

      / / Sign
      Object [] res = new FirmaXML (). SignFiles (certificate, dataToSign, PrivateKey, provider);

      / / Save the file signature in the user's home
      UtilidadTratarNodo.saveDocumentToOutputStream ((Document) res [0], new FileOutputStream ("c: \\ temp \\ \\ signed.xml"), true);
      }}




      If you run this code (changing the routes of the certificate, and xml) is generated you can validate xml

      here and verify that the signature is correct. This example uses the signature policy 3.1 of facturae format, if you want to change company policy need to change the allocation PoliciesManager.POLICY_SIGN variables and PoliciesManager.POLICY_VALIDATION.

      I have not tried to sign bills with another type of signature, as it works, maybe not. In the file that you downloaded above include all the libraries of the ministry converted to dll, and the modified sources if you want to make more modifications. If you need more IKVM.NET the libraries can be downloaded from its official website.

      I hope this post has been helpful.

      Any input, comments, or donations are welcome.




    0 comments:

    Post a Comment