miércoles, 20 de mayo de 2015

Autenticación con SII certificado pfx Linux


Para consumir WSDL del SII es necesario autenticarse, dicha autenticacion se realiza por medio de un certificado digital emitido por una entidad certificadora,ejemplo e-sign,  el cual sirve para certificar una acción o un documento.

El SII   tiene un proceso  de autenticación el cual consiste:
 1.- obtener una semilla.
 2.- certificar la semilla.
 3.- enviar semilla certificada.
 4.- obtener token de acceso.


Antes de realizar alguna de estas acciones voy a mostrar como extraer el certificado digital desde  nuestro navegador.
En este caso lo haré con un certificado emitido por e-sign .Lamentablemente e-sign solo emite certificados por medios de Windows/IExplorer , así que en una maquina virtual o en un equipo windows realizamos los siguientes pasos:

1.- Exportar certificado en PFX :
   1.1 lo primero que debes hacer es abrir el internet explorer  ir a opciones de internet   pestaña contenido:
automatico

  1.2  Presionar certificados  y seleccionar el certificado a exportar:
   

1.3 Seleccionar exportar y se nos abrira una ventana similar a esta, le damos en siguiente :
 

1.4  debes seleccionar "Exportar la clave privada"  y damos en siguiente:


1.5   luego pasamos hacemos la siguiente selección, y nuevamente presionamos siguiente:
 
automaticoautomatico

1.6 en este punto nos pedira que ingresemos una contraseña por seguridad, ingresamos la que mas nos acomode y la recordaremos, puesto que es necesario para el proceso de autenticacion con el SII:



1.7 luego seleccionamos donde guardar nuestro certificado:


1.8 nos saldrá una ventana como la siguiente y le damos aceptar:

1.9  y luego nos dirá  que la exportación fue exitosa.

Una ves  obtenido el certificado podemos realizar el proceso completo de autenticacion automático con el siguiente script   https://github.com/waflessnet/sii-bash/ , tanto en certificación como en producción.

Los siguientes párrafos explican como funciona el script.

2.- XMLSEC clave privada y certificado.

El SII nos pide firmar una semilla en formato XML,  en linux existe una herramienta que nos permite realizar este proceso: xmlsec1.
Para firmar con xmlsec necesitamos  la clave privada ,el certificado  y un template a utilizar.
Para  esto extraemos dicha clave privada y certificado del archivo .pfx que exportamos desde windows.
Ahora desde linux , gracias openssl, extraemos dichos documentos:

clave privada:
# openssl pkcs12 -in certificado.pfx -out claveprivada.pem -nocerts -nodes

certificado:
# openssl pkcs12 -in certificado.pfx -out certificado.pem -nokeys -clcerts

Estas instrucciones nos generan dos archivos  claveprivada.pem y certificado.pem   ahora utilizamos el siguiente template (http://pastebin.com/edueUfmB ) para firmar la semilla :

  1. <?xml version="1.0"?>
  2. <getToken>
  3. <item>
  4. <Semilla></Semilla>  
  5. </item>
  6. <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
  7. <SignedInfo>
  8. <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
  9. <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
  10. <Reference URI="">
  11. <Transforms>
  12. <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
  13. </Transforms>
  14. <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
  15. <DigestValue/>
  16. </Reference>
  17. </SignedInfo>
  18. <SignatureValue/>
  19. <KeyInfo>
  20. <KeyValue>
  21. <RSAKeyValue>
  22. <Modulus/>
  23. <Exponent/>
  24. </RSAKeyValue>
  25. </KeyValue>
  26. <X509Data>
  27. <X509Certificate/>
  28. </X509Data>
  29. </KeyInfo>
  30. </Signature>
  31. </getToken>

3.- Firmar

  Ya con los datos obtenidos en el punto 2  vamos a firmar el template  para ello debemos colocar la semilla obtenida del  consumo del WSDL (https://maullin.sii.cl/DTEWS/CrSeed.jws?WSDL ) , cabe destacar que  todo esto lo realizaremos  en ambiente  certificación, dentro del tag : <semilla></semilla> , asumiremos que obtenemos "semilla123435" del servicio , luego   con sed  y regex  remplazamos:

sed 's/<Semilla>.*<\/Semilla>/<Semilla>semilla123435<\/Semilla>/g' template.xml > semilla.xml

Ahora firmamos el template  xml con la herramienta xmlsec1 :

xmlsec1 --sign --privkey-pem claveprivada.pem,certificado.pem --pwd 'contraseña$car@qass' semilla.xml > semilla-firmada.xml

Debemos modificar  la semilla firmada   para agregar el formato del WSDL que exige el SII, nuevamente con sed y regex :

sed -i '1s|<\?|<pszXml xsi:type="xsd:string"><!\[CDATA\[<|' semilla-firmada.xml
sed -i '79s|<\/getToken>|<\/getToken>\]\]><\/pszXml>|' semilla-firmada.xml

Luego en el request que exige el SII ( https://github.com/waflessnet/sii-bash/blob/master/rGetToken.xml)  lo seteamos   para agregar nuestro XML :

 sed -n "1,4p" rGetToken.xml > request-token.xml
cat tmp/semilla-firmada.xml >> request-token.xml
sed -n "6,8p" rGetToken.xml >> request-token.xml

Una vez realizado esto llamamos al WSDL para obtener el token: https://mauliin.sii.cl/DTEWS/GetTokenFromSeed.jws?wsdl  ,todo esto  certificación, enviamos  request-token.xml

 Con esto obtenemos el Token de acceso en el servicio.

El procedimiento de consumo  completo del SII automático , es decir llamadas a los WSDL y respectiva firma,   lo encuentras en mi github : https://github.com/waflessnet/sii-bash/

Este script obtiene el Token directamente,  es decir, desde el pfx  obtiene el certificado y la clave privada  luego obtiene la semilla ,esta semilla la firma  y  la envia    al WSDL https://xxxxxx.sii.cl/DTEWS/GetTokenFromSeed.jws  ,  y nos entrega el token.

El script bash nos permite obtener el token de acceso en certificación (maullin)  tanto como en  producción (palena).














martes, 6 de enero de 2015

Django 1.7 Linux SQL Server ODBC

Vamos a realizar una conexión hacia un  SQL Server ( en mi caso fue hacia un SQL Server2012)  con django 1.7 , se entiende   debes tener instalado Django, para ello  vamos a ocupar  odbc y tds .
La instalación y configuración que vamos a realizar  puede servir no solo para django sino también   para otros accesos mediante odbc .

Lo que necesitamos es :

1.- freetds y el la libreria unix ODBC
2.- el paquete django-pyodbc-azure


Instalamos el odbc:
Centos:
# yum install unixODBC unixODBC-devel libtool-ltdl libtool-ltdl-devel
Debian:
#  apt-get install unixODBC unixODBC-dev

luego el freetds :
Centos;
#yum install freetds
Debian:
#apt-get install freetds

Debemos configurar los dos componentes que instalamos , primero lo haremos con FreeTDS. La ruta por default es ; /etc/freetds.conf  agregamos al final del archivo lo siguiente;

[mssql_freetds]
        host = IP o Nombre del Sql Server
        port = 1433
        tds version = 8.0

Luego debemos configurar el odbcinst, su ruta por default es: /etc/odbcinst.ini vamos a agregar al final del archivo :

[driver_freetds]
Description = ODBC for Microsoft SQL
Driver      = /usr/lib64/libtdsodbc.so
Setup       = /usr/lib64/libtdsS.so
UsageCount  = 1
-----------------------------EXTRA -------------------------
las rutas de las librerías pueden variar de versión de S.O como de distribución, sino sabes donde esta puedes ocupar  algunos comandos (siempre con root):
-- actualizamos el cache
# updatedb
--para buscar donde esta  el driver:
# locate libtdsodbc.so
--para buscar donde esta la librería de  setup:
# locate libtdsS.so

te darán una pequeña ayuda en donde  pueden estar las librerías.
------------------------------------------------------------------
Seguimos,  ahora nos falta configurar el odbc,que esta en la ruta por default : /etc/odbc.ini  ,para este caso presta atención a los nombre en colores, agregamos las siguientes lineas al final del archivo :

[mssql_freetds_django]
Driver                     = driver_freetds
ServerName            = mssql_freetds
Database                 =  DataBaseAconectar
TDS_Version          =8.0

Si te fijas hemos definido el Driver "driver_freetds"  que configuramos en /etc/odbcinst.ini  y en ServerName definimos el  "mssql_freetds" que definimos en /etc/freetds.conf  ahora hacemos una pequeña prueba , en donde colocamos el usuario y contraseña de la base a la cual nos queremos conectar :


# isql -v mssql_freetds_django  usuario password

deberían obtener una salida similar a :



Ahora  ha  django 1.7 !, para comenzar hay que instalar el paquete django-pyodbc-azure , con pip por ejemplo :

pip install django-pyodbc-azure

una vez que haya instalados , nos vamos a el settings.py de  nuestra aplicación y  modificamos la siguiente configuración :

DATABASES = {
    'default': {
        'NAME': 'DataBaseAconectar',
        'ENGINE': 'sql_server.pyodbc',
        'HOST': 'mssql_freetds',
        'USER': 'usuario',
        'PASSWORD': 'password',
        'PORT': '1433',                      .
        'OPTIONS': {
                'driver': 'driver_freetds',
                'dns':'mssql_freetds_django',
                'MARS_Connection': True,
        },
    }
}

he resaltado con colores las configuraciones, para que tengas aún más claro que ocurre. Si te das cuenta en 'HOST' no va una ip tampoco un nombre de maquina, sino mas bien la configuración que  hicimos en /etc/freetds.conf 
Ya pueden acceder a  su base de datos Sql server  !!




Fuentes :
http://stackoverflow.com/questions/18232386/freetds-working-but-odbc-cannot-connect
https://github.com/michiya/django-pyodbc-azure
http://www.perlmonks.org/?node_id=1008467