wiki:comoUsarElApi

¿Cómo usar el API de Murachi?

Detalles de seguridad

Todos los recursos del API requieren autenticación básica HTTP (Basic Authentication). Por esta razón, en todas las solicitudes debe estar presente el encabezado Authorization lleno con los valores app_id y app_key que se generará para su consumo. Por ejemplo si las credenciales de su aplicación son las siguientes:

  • app_id: murachi.test
  • app_key: 12345678

necesitará codificarlas con el algoritmo Base64: Base64(app_id:app_key). El resultado debería ser como el siguiente encabezado HTTP: Authorization: Basic aG9sYTptdW5kbw==.

Puede convertir credenciales a Base64 con la siguiente línea de comando:

echo -n APP_ID:APP_KEY | base64

reemplazando APP_ID y APP_KEY con sus respectivas credenciales.

NOTA: inicialmente para propósitos de prueba se estarán utilizando las credenciales

  • app_id: admin
  • app_key: admin

Esto da como resultado: YWRtaW46YWRtaW4=.

Entonces mientras se habilita el proceso de generación de API_KEY para clientes del API se utilizará lo siguiente:

Authorization: Basic YWRtaW46YWRtaW4=

al momento de consumir un recurso de Murachi.

Documentación del API

icono de documentación

Para consumir o hacer llamadas a los recursos del servicio Murachi puede revisar el siguiente enlace: https://murachi.cenditel.gob.ve/apidoc/. Allí encontrará todos los recursos disponibles hasta el momento con sus parámetros, respuestas, errores y ejemplos de uso.

Prueba básica con Ruby

En el siguiente código se cargan dos (02) archivos de texto y se agregan a un contenedor BDOC a través del recurso https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/bdocs/cargas. Luego se listan los archivos que tiene el contenedor con el recurso https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/bdocs/archivos/lista/%s. Seguidamente se prepara la firma del contenedor BDOC a través del recurso https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/bdocs/firmas/pre que retorna el hash que se debe firmar en el cliente con la clave privada protegida en el dispositivo criptográfico. Luego se completa la firma del contenedor BDOC a través del recurso https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/bdocs/firmas/post. Finalmente se verifica la firma del contenedor BDOC a través del recurso https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/56143d89-1029-4ae4-b023-ca4367a8f34d

Para mayor información y documentación de los recursos disponibles siga el enlace: https://murachi.cenditel.gob.ve/apidoc/.

  • Crear el archivo multipart.rb con el siguiente contenido:
require 'net/https'
require 'net/http/post/multipart'
require "openssl"
require "json"

# Cargas archivo y crear contenedor BDOC
#uri = URI.parse('https://192.168.12.125:8443/Murachi/0.1/archivos/bdocs/cargas')
@uri = URI.parse('https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/bdocs/cargas')
@req = Net::HTTP::Post::Multipart.new @uri.path,
  "f1" => UploadIO.new(StringIO.new("cadena de prueba"), "text/plain", "file.txt"),
  "f2" => UploadIO.new(StringIO.new("SEGUNDA cadena de prueba"), "text/plain", "file2.txt")
# Agregar cabezera para autenticación con murachí
@req['Authorization'] = 'Basic YWRtaW46YWRtaW4='

@http = Net::HTTP.new(@uri.host, @uri.port)
@http.use_ssl = true
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
# RESPUESTA --->>
@res = @http.request(@req)
# Body
@json_resp = JSON.parse(@res.body)
puts @json_resp['containerId']

# Listar archivos del contenedor registrado en la llamada anterior
@container_id = @json_resp['containerId']
@uri = URI.parse 'https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/bdocs/archivos/lista/%s' % @container_id
@req = Net::HTTP::Get.new @uri.path
@req['Authorization'] = 'Basic YWRtaW46YWRtaW4='
@res = @http.request(@req)
@json_resp = JSON.parse(@res.body)
@json_resp['dataFiles'].each do |file|
  puts file['filename']
end

# Prepara firma de un contenedor
@certificate = "30820512308202FAA003020102020119300D06092A864886F70D01010B05003081AA310B3009060355040613025645310F300D060355040813064D6572696461310F300D060355040713064D65726964613111300F060355040A130843454E444954454C310E300C060355040B13054749445349312E302C06035504030C254175746F7269646164206465204365727469666963616369C3B36E2064656C2047494453493126302406092A864886F70D0109011617616367696473694063656E646974656C2E676F622E7665301E170D3135303930383135333930305A170D3136303930383135333930305A308198310B3009060355040613025645310F300D060355040813064D6572696461310F300D060355040713064D65726964613111300F060355040A130843454E444954454C31133011060355040B130A4465736172726F6C6C6F311630140603550403130D4A6F726765205265646F6E646F3127302506092A864886F70D01090116186A7265646F6E646F4063656E646974656C2E676F622E766530820122300D06092A864886F70D01010105000382010F003082010A0282010100E27AC29BDC3196EFD1F388B6B415F965E7407616448A2A3AF40C7D3E2BFCEA7531A922578B444ACA4386A1744DDCD9507221CCCE9D3A9B81D46FFE274BA378D8413DED29CF596C5F5D7967C9D2E8F1EC1ACDD90582FD8DE055401D9906678DDB4A2F9E4E0FF8041740EAB6A4DFEF308AC1D05824FE4C5CCAA9435F8CAA3C73F937E1BA6F3075CCD2B5D8069BD937B8D9FFD34CB3F8E6B4CFA13BE62110DD677FC4653043ECE4D4E4D9373E01165E6BD33D2B8D1A477AA18E8F1CF68C6476BB30B187BAF2DDC0B8C06DF8292E4C4D57933A44E0B5AA17CC09FE85D4EB9A3F8082F603326FCA407C51691886ED47C15637AE75339F23E8F549F7DCB54CBC6555390203010001A3533051300C0603551D130101FF04023000300E0603551D0F0101FF0404030204F0301106096086480186F84201010404030205A0301E06096086480186F842010D0411160F786361206365727469666963617465300D06092A864886F70D01010B05000382020100556A0C471B30503343A375F54C0DCD345B3BB895A059E734315375B919AEB404C22E897A50D4B983B9480B4BBB48861C8BF27634E185460C95DE010D0DBB0B3091C439AB99ED862134FAD0610F5D7304F0365781FD35FD6340ACBD8EB05866CB44DB02590A06EAAF3978B6EA224F6B226B528DE841273146AFA873A56EE82B149817545074F40B97A26093A76DE174EEBC12285023FAA57A3E24ACC7D3BB0360FFF6D71AB3E3F30EBC07A14F73B974F4623421F762F155E7487F1C44E89F477BAB4A9843FC07DB5AF90943C298DFF5E9B3FDF3358AD145C5138F312170D767F0FEFD2DE7B3BDCD2F54E999A9E10E7B3C7AAF8AACDF65DE9D6FCDBC0E190048623AA494BBB6BA3A0FC0D2E1279D61D36D3B107C48236FA771CD6ED204C97D7AD6369E442DAF8A6E78D7104D4D1C19B0040039CCD20B3A0049236F726AC145AFD37FD54EA0FA44C1CD3131B858DE0D9A904B833DB33F66D75AA7396215561BEB9A0830B4282A08A57944C516F9406A01906D26E6A542861C057ADB34D66BDA2E92A5B62B30DAAD9F27F35348FD3481F18023C2687F8A288BB10B1FBBF5351140DA3BF67AFDFDE805618A355A3BE162C3F93C3F87370B815583EF31CBC68BF1F9CF1B04D6DAA685FD46FF4C5D507BF2C370B9120F07A33F2F9FABA4102A004D8F1CD6136FD63F15E3C26AC73B9ED8BDA930B21DD85F4CF9F778C12DA4B0E459B5BA"
@parameters = {"fileId" => @container_id,
               "certificate" => @certificate,
               "city" => "Rubio",
               "state" => "Tachira",
               "postalCode" => "1234",
               "country" => "Venezuela",
               "role" => "Militar",
               "addSignature" => "false"}
@headers = { "Content-Type" => 'application/json',
             "Authorization" => 'Basic YWRtaW46YWRtaW4='}
#@uri = URI.parse("https://192.168.12.125:8443/Murachi/0.1/archivos/bdocs/firmas/pre")
@uri = URI.parse("https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/bdocs/firmas/pre")
@http = Net::HTTP.new(@uri.host, @uri.port)
@http.use_ssl = true
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
@res = @http.post(@uri.path,@parameters.to_json,@headers)
@hash = JSON.parse(@res.body)["hash"]
puts @hash

# Completar firma de contenedor
@parameters = {"containerId" => @container_id,
               "signature" => @hash}
@headers = { "Content-Type" => 'application/json',
            "Authorization" => 'Basic YWRtaW46YWRtaW4='}
#@uri = URI.parse("https://192.168.12.125:8443/Murachi/0.1/archivos/bdocs/firmas/pre")
@uri = URI.parse("https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/bdocs/firmas/post")
@http = Net::HTTP.new(@uri.host, @uri.port)
@http.use_ssl = true
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
@res = @http.post(@uri.path,@parameters.to_json,@headers)
puts @res.body  


# verificacion
# Listar archivos del contenedor registrado en la llamada anterior
@container_id = '56143d89-1029-4ae4-b023-ca4367a8f34d'
@uri = URI.parse 'https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/%s' % @container_id
@req = Net::HTTP::Get.new @uri.path
@req['Authorization'] = 'Basic YWRtaW46YWRtaW4='
@res = @http.request(@req)
@json_resp = @res.body
puts @json_resp

  • Ejecutar:

ruby multipart.rb

Prueba básica con Python

A continuación se muestra un código muy básico para ilustrar cómo se pueden consumir recursos de Murachí desde el lenguaje python. Para correr el script python pruebaMurachi.py se requiere instalar el framework requests, M2Crypto y el framework web tornado.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os, uuid

from M2Crypto import X509


import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

import requests
from requests.auth import HTTPBasicAuth

from tornado.options import define, options

define("port", default=8888, help="run on the given port", type=int)

__UPLOADS__ = "/tmp/"

# mensaje hola mundo
class IndexHandler(tornado.web.RequestHandler):
	def get(self):
		greeting = self.get_argument('greeting', 'Hello')
		self.write(greeting + ', friendly user!\n')

# para obtener la version del servicio web
class VersionHandler(tornado.web.RequestHandler):
	def get(self):		
		# verify=False para no verificar el certificado del servidor web
		# auth=() para la autenticacion basica de HTTP
		r = requests.get('https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/version', verify=False, auth=('admin', 'admin'))
		#r = requests.get('https://192.168.12.125:8443/Murachi/0.1/archivos/version', verify=False, auth=('admin', 'admin'))
		self.write(r.text)
		#r.json()
		#self.write(r.raise_for_status())
		


# para subir un archivo 
class UploadHandler(tornado.web.RequestHandler):
	def get(self):
		#files = {'file': open('/tmp/reports.txt', 'rb')}
		# subir un pdf
		files = {'file': open('/home/cenditel/desarrollo/murachi/convenioSUSCERTE-CENDITEL.pdf', 'rb')}
		r = requests.post('https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/cargar', verify=False, auth=('admin', 'admin'), files=files)
		#r = requests.post('https://192.168.12.125:8443/Murachi/0.1/archivos/cargar', verify=False, auth=('admin', 'admin'), files=files)
		#self.write(r.text)
		r.json()
		fileId = r.json()['fileId']
		self.write(fileId)
		self.write('\n')

		#verificar si el documento esta firmado
		#r2 = requests.get('https://192.168.12.125:8443/Murachi/0.1/archivos/'+fileId, verify=False, auth=('admin', 'admin'), files=files)
		r2 = requests.get('https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/'+fileId, verify=False, auth=('admin', 'admin'), files=files)
		self.write(r2.text)
		
# para obtener estadisticas basicas
class StatisticsHandler(tornado.web.RequestHandler):
	def get(self):
		r = requests.get('https://murachi.cenditel.gob.ve/Murachi/0.1/archivos/estadisticas', verify=False, auth=('admin', 'admin'))
		self.write(r.text)
		

		
		

# manejador principal
class MainHandler(tornado.web.RequestHandler):
	def get(self):
		self.write("""
			<form name="input" action="/loadfile" method="post" enctype="multipart/form-data" >
			archivo: <input type="file" name="fileToUpload"><br>
			<input type="submit" value="Enviar"/>
			</form>
			""")
	def write_error(self, status_code, **kwargs):
		self.write("Gosh darnit, user! You caused a %d error." % status_code)



class LoadHandler(tornado.web.RequestHandler):
	def post(self):
		#print self.request.arguments
		#self.write(self.request.arguments)
		#self.write("hola")
		#archivo = self.get_argument("file",'')

		fileinfo = self.request.files['fileToUpload'][0]
		fname = fileinfo['filename']
		self.write(fname+'\n')
		extn = os.path.splitext(fname)[1]
		cname = str(uuid.uuid4()) + extn
		fh = open(__UPLOADS__ +cname, 'w')
		fh.write(fileinfo['body'])
		self.write('archivo subido: '+cname+'\n')
		#self.finish(cname + " is uploaded! Check %s folder" %__UPLOADS__)

		mypage = u"""Hola mundo"""
		self.write(mypage)


if __name__ == "__main__":
	tornado.options.parse_command_line()
	#app = tornado.web.Application(handlers=[(r"/", IndexHandler)])
	app = tornado.web.Application(handlers=[(r"/", MainHandler), 
						(r"/index", IndexHandler),
						(r"/version", VersionHandler),
						(r"/upload", UploadHandler),
						(r"/estadisticas", StatisticsHandler),
						(r"/loadfile", LoadHandler)
	#					(r"/loadCertificate", LoadCertificateHandler)
						])
	
	http_server = tornado.httpserver.HTTPServer(app, ssl_options={"certfile": "server.crt", "keyfile": "server.key"})
	http_server.listen(options.port)
	tornado.ioloop.IOLoop.instance().start()

Para ejecutar el script python:

# python pruebaMurachi.py

Luego en un navegador web se pueden probar algunos recursos.

  • Para obtener la versión del servicio:

  • Para cargar un archivo al servicio y verificar firmas:

  • Para obtener estadísticas básicas de firmas y verifcaciones:

Last modified 3 years ago Last modified on Nov 6, 2015, 10:27:28 AM

Attachments (7)

Download all attachments as: .zip