FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Firmar facturae
Posts: 174
Joined: Wed Nov 29, 2017 11:42 AM
Re: Firmar facturae
Posted: Mon Jan 28, 2019 12:09 PM

Bien, poniendo a funcionar la firma electr贸nica de facturas, ahora me encuentro con un problema en algun certificado...

Si consulto los alias de certificados en mi almac茅n desde cmd...

AutofirmaCommandLine.exe listaliases -store windows
...
INFO: Solicitando los alias al KeyStore (SunMSCAPI version 9)
40123456X NOMBRE Y APELLIDOS (R: B12123123)
Disp. software de seguridad:50123456X NOMBRE2 Y APELLIDOS2 (R: B12123123)?s FNMT-RCM I
...

me devuelve los dos "alias" de los certificados que tengo instalados...
Bien, pues el segundo no se porqu茅 narices me saca que es software de seguridad...
Por mas que he provado combinaciones (solo con el nombre, nombre y contenido entre parentesis), TODO el texto. Pues nada, que no reconoce ese "nombre" como certificado instalado.

Alguien le puede haber surgido este problema???

Lo he probado de hacer firmar con el programa Autofirma y si que lo firma correctamente, pero con el comando AutofirmaCommandLine, no hay manera de que me "pille" esa firma.

驴?驴?

Gracias por vuestro tiempo!!!

Un Saludo,

Xevi.



Aprendiz de la vida!!!
Posts: 17
Joined: Tue Oct 06, 2015 07:06 AM
Re: Firmar facturae
Posted: Mon Jan 28, 2019 12:41 PM
Buenas, os pongo de nuevo el c贸digo con la correcci贸n de pulsar cancelar en el di谩logo.
Ahora devuelve una cadena vac铆a al pulsar cancelar:

Code (fw): Select all Collapse
#include "fivewin.ch"


func main()


聽 聽MsgInfo("Seleccionado certificado: "+ToTxt(SELCERT()), "CryptoApi")



return nil

//*****************************************************************************
//*****************************************************************************

function ToTxt( uVal )

聽 聽local cType := ValType( uVal )

聽 聽do case
聽 聽 聽 case cType == "C" .or. cType == "M"
聽 聽 聽 聽 聽 聽return uVal

聽 聽 聽 case cType == "D"
聽 聽 聽 聽 聽 聽return DToC( uVal )

聽 聽 聽 case cType == "L"
聽 聽 聽 聽 聽 聽return If( uVal, ".T.", ".F." )

聽 聽 聽 case cType == "N"
聽 聽 聽 聽 聽 聽return AllTrim( Str( uVal ) )

聽 聽 聽 case cType == "B"
聽 聽 聽 聽 聽 聽return "{|| ... }"

聽 聽 聽 case cType == "A"
聽 聽 聽 聽 聽 聽return "{ ... }"

聽 聽 聽 case cType == "O"
聽 聽 聽 聽 聽 聽return If( __ObjHasData( uVal, "cClassName" ), uVal:cClassName, uVal:ClassName() )

聽 聽 聽 case cType == "H"
聽 聽 聽 聽 聽 聽return "{=>}"

聽 聽 聽 otherwise
聽 聽 聽 聽 聽 聽return ""
聽 聽endcase

return nil

//*****************************************************************************
//*****************************************************************************

#pragma BEGINDUMP

#include <windows.h>
//#include <psapi.h>
//#include <hbapi.h>
//#include <hbapierr.h>
//#include <hbapiitm.h>
//#include <wincrypt.h>

#define CRYPTUI_SELECT_LOCATION_COLUMN 0x000000010

//Definir el prototipo de las funciones:
typedef HCERTSTORE (WINAPI * PTYPECERTOPEN) (HCRYPTPROV, LPTSTR);
typedef PCCERT_CONTEXT (WINAPI * PTYPECERTSELECTDLG) (HCERTSTORE, HWND, LPCWSTR, LPCWSTR, DWORD, DWORD, void*);
typedef PCCERT_CONTEXT (WINAPI * PTYPECERTENUM) (HCERTSTORE, PCCERT_CONTEXT);
typedef DWORD (WINAPI * PTYPECERTGETNAME) (PCCERT_CONTEXT, DWORD, DWORD, VOID*, LPTSTR, DWORD);
typedef DWORD (WINAPI * PTYPECERTNAMETOSTR) (DWORD, PCERT_NAME_BLOB, DWORD, LPTSTR, DWORD);
typedef BOOL (WINAPI * PTYPECERTFREECC) (PCCERT_CONTEXT);
typedef BOOL (WINAPI * PTYPECERTCLOSESTORE) (HCERTSTORE, DWORD);

HB_FUNC(SELCERT)
{

聽 聽// Hay varios ejemplos en: <!-- m --><a class="postlink" href="https://msdn.microsoft.com/en-us/librar">https://msdn.microsoft.com/en-us/librar</a><!-- m --> ... 61(v=vs.85).aspx

聽 聽HCERTSTORE hStore;
聽 聽PCCERT_CONTEXT PrevContext, CurContext;
聽 聽PCHAR sNombre;
聽 聽DWORD cbSize;
聽 聽PHB_ITEM pArray;
聽 聽PHB_ITEM pItem;
聽 聽PCCERT_CONTEXT 聽 pCertContext;
聽 聽// Cargamos las librer铆as de las que queremos la direcci贸n de las funciones.
聽 聽HMODULE HCrypt = LoadLibrary("Crypt32.dll");
聽 聽HMODULE HCrypt2 = LoadLibrary("Cryptui.dll");

聽 聽// Declaramos el tipo de puntero a la funci贸n, tenemos la definici贸n arriba.
聽 聽PTYPECERTOPEN 聽 聽pCertOpen;
聽 聽PTYPECERTSELECTDLG 聽 聽pCertSelectDlg;
聽 聽PTYPECERTGETNAME pCertGetName;
聽 聽PTYPECERTNAMETOSTR pCertNameToStr;
聽 聽PTYPECERTFREECC pCertFreeCC;
聽 聽PTYPECERTCLOSESTORE pCertCloseStore;


聽 聽if (HCrypt != NULL && HCrypt2 != NULL){
聽 聽 聽 //Sacamos el puntero todas las funciones que vamos a usar mediante GetProcAddress:
聽 聽 聽 #ifdef UNICODE
聽 聽 聽 聽 聽pCertOpen 聽 聽= (PTYPECERTOPEN) GetProcAddress(HCrypt, "CertOpenSystemStoreW");
聽 聽 聽 聽 聽pCertGetName = (PTYPECERTGETNAME) GetProcAddress(HCrypt, "CertGetNameStringW");
聽 聽 聽 #else
聽 聽 聽 聽 聽pCertOpen 聽 聽= (PTYPECERTOPEN) GetProcAddress(HCrypt, "CertOpenSystemStoreA");
聽 聽 聽 聽 聽pCertGetName = (PTYPECERTGETNAME) GetProcAddress(HCrypt, "CertGetNameStringA");
聽 聽 聽 #endif
聽 聽 聽 pCertSelectDlg = (PTYPECERTSELECTDLG) GetProcAddress(HCrypt2, "CryptUIDlgSelectCertificateFromStore");
聽 聽 聽 pCertFreeCC 聽= (PTYPECERTFREECC) GetProcAddress(HCrypt, "CertFreeCertificateContext");
聽 聽 聽 pCertCloseStore 聽= (PTYPECERTCLOSESTORE) GetProcAddress(HCrypt, "CertCloseStore");
聽 聽}

聽 聽if (pCertOpen){
聽 聽 聽 // Llamada a CertOpenSystemStore:
聽 聽 聽 hStore = pCertOpen(NULL, TEXT("MY"));
聽 聽}

聽 聽if (hStore){
聽 聽 聽 pCertContext = pCertSelectDlg(hStore, NULL, NULL, NULL, CRYPTUI_SELECT_LOCATION_COLUMN, 0, NULL);

聽 聽 聽 if (pCertContext!=NULL){
聽 聽 聽 聽 聽cbSize = pCertGetName(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0);
聽 聽 聽 聽 聽if (cbSize>0) {
聽 聽 聽 聽 聽 聽 //Reservamos la memoria que necesitamos para el texto que recibiremos
聽 聽 聽 聽 聽 聽 sNombre = (LPTSTR)malloc(cbSize * sizeof(TCHAR));

聽 聽 聽 聽 聽 聽 pCertGetName(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, sNombre, cbSize);


聽 聽 聽 聽 聽 聽 // Llamada a CertFreeCertificateContext:
聽 聽 聽 聽 聽 聽 pCertFreeCC(pCertContext);
聽 聽 聽 聽 聽}
聽 聽 聽 } else {
聽 聽 聽 聽 聽sNombre = "";
聽 聽 聽 }

聽 聽 聽 // Cerrar el almacen de certificados:
聽 聽 聽 // Llamada a CertCloseStore:
聽 聽 聽 pCertCloseStore(hStore, 0);
聽 聽 }

聽 聽 FreeLibrary(HCrypt);
聽 聽 FreeLibrary(HCrypt2);

聽 聽 hb_retc(sNombre);

}

#pragma ENDDUMP


Aunque funciona, el c贸digo dista mucho de ser perfecto, hay muchas comprobaciones que no se hacen o que se hacen y no terminan la ejecuci贸n. Adem谩s, el di谩logo muestra todos los certificados, no solo los que tengan una clave privada, etc.
Pero vamos, para el uso que le vais a dar, funciona.


Por cierto, ya que estamos con el tema de facturae, si alguien tiene alguna clase que encapsule la generaci贸n del XML de la factura, se lo agradecer铆a.

Un saludo.
Posts: 174
Joined: Wed Nov 29, 2017 11:42 AM
Re: Firmar facturae
Posted: Wed Jan 30, 2019 08:56 PM

Siguiendo con el tema de selecci贸n de certificado para procesar la firma seguidamente con AutofirmaCommandLine...

He localizado el error (o el porqu茅) que no me deja proceder a la firma con ese certificado.
Por lo visto, ese certificado tiene el campo "Nombre descriptivo" relleno, y es precisamente por ese motivo que no me deja utilizarlo luego.
O sea, SI UN CERTIFICADO tiene el campo "Nombre descriptivo" relleno (no vacio), no deja utilizar el certificado.

Igual es por algun par谩metro que no lo estoy utilizando correctamente en el AutofirmaCommandLine,
Pero...
Yo lo que he hecho es eliminar el contenido de ese campo en ese certificado... y ahora ya SI me funciona correctamente.

No se si a alguien le puede suceder lo mismo que a mi, pero aqu铆 lo dejo, por si acaso!!!
Es una soluci贸n.

Gracias por vuestro tiempo.

Un Saludo,

Xevi.



Aprendiz de la vida!!!
Posts: 728
Joined: Fri Oct 07, 2005 07:38 AM
Re: Firmar facturae
Posted: Thu Jan 31, 2019 07:25 AM

Gracias Xevi, no se me ha dado el caso ... a煤n ;-) Es bueno saberlo.

Angel Salom
Visionwin Software - https://www.visionwin.com
------------------------------------------------------------
fwh 19.05 - harbour 3.2 - bcc 7.4
Posts: 5
Joined: Mon May 20, 2019 03:49 PM
Re: Firmar facturae
Posted: Thu Sep 28, 2023 11:54 AM

Ol谩 Dario, voc锚 tem as fun莽玫es para assinar um XML com o certificado?

Aqui no Brasil eu uso o CAPICOM para usar o Certificado Digital, mais eu gostaria de usar os recursos da WinCrypt para pegar o certificado e assinar o XML.

Algu茅m do F贸rum pode me ajudar?

Posts: 1710
Joined: Tue Oct 28, 2008 06:26 PM
Re: Firmar facturae
Posted: Thu Sep 28, 2023 12:16 PM
Estimado cwanderlei_cardoso

Intenta con Chilkat
https://www.example-code.com/foxpro/xmldsig.asp
Saludos,



Adhemar C.
Posts: 5
Joined: Mon May 20, 2019 03:49 PM
Re: Firmar facturae
Posted: Thu Sep 28, 2023 06:45 PM

Obrigado Adhemar,

Mais quero utilizar o wincrypt do windows para n茫o ter de instalar nada, usar de forma nativa.

Hoje eu utilizo a dll do Capicom para assinar os XML de notas fiscais.

Continue the discussion