Todos mis procesos sobre CFDIs estan hechos en un Delphi viejo (Delphi 7) y ya estoy migrando (especificamente a XE7)... bueno, les comento que al tratar de timbrar el PAC (varios) me regresan el mensaje de Sello Invalido, lo valido con el ValicaCFDI y no me marca error, estoy creyendo que el problema es con el rollo ese de los strings, que cambian de los viejos delphis a lo nuevos... alguien le pasó lo mismo?? alguna idea??
Les paso las funciones (compartidas aqui desde los albores de este rollo de los CFDIs):
Código: Seleccionar todo
function BinToBase64(const PDat: PBYTE; const DatLen: DWORD): string;
const BaseTable: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var s, s1: string;
i, p, len, n, Addnum: DWORD;
PBin: PBYTE;
begin
result := '';
S := '';
addnum := 0;
PBin := PDat;
for i := 1 to DatLen do
begin
S := S + IntToHex(PBin^, 2);
PBin := PBYTE(DWORD(PDat) + i);
end;
case (length(s) mod 3) of
0: addnum := 0;
1: begin
s := s + '00';
addnum := 2;
end;
2: begin
s := s + '0';
addnum := 1;
end;
end;
len := length(s) div 3;
for i := 1 to len do
begin
s1 := midstr(S, i * 3 - 2, 3);
p := strtoint('$' + s1);
n := p div 64;
result := result + basetable[n + 1];
n := p mod 64;
result := result + basetable[n + 1];
end;
if addnum = 1 then result := result + '==';
if addnum = 2 then result[length(result)] := '=';
end;
Código: Seleccionar todo
function RSALoadPrivateKey(const AFileName, APassPhrase: string): PRSA;
var
bp: pBIO;
fn, pp: PChar;
pk: PRSA;
begin
fn := PChar(ansistring(AFileName));
pp := PChar(ansistring(APassPhrase));
bp := BIO_new(BIO_s_file());
BIO_read_filename(bp, fn);
pk := nil;
Result := PEM_read_bio_RSAPrivateKey(bp, pk, nil, pp);
BIO_free(bp);
if Result = nil then
raise Exception.Create('Private key failure.' + GetErrorMessage);
end;
Código: Seleccionar todo
function LoadPrivateKey(const AFileName, APass: string): PEVP_PKEY;
var
rkey: PRSA;
begin
rkey := RSALoadPrivateKey(AFileName, APass);
Result := EVP_PKEY_new;
EVP_PKEY_assign(Result, EVP_PKEY_RSA, rkey);
end;
Código: Seleccionar todo
function SelloDigital(llaveprivada,cadenaoriginal: string): string;
var Len: cardinal;
mdctx: EVP_MD_CTX;
inbuf: array [0..8192] of ansichar;
outbuf: array [0..1023] of ansichar;
key: pEVP_PKEY;
begin
StrPCopy(inbuf,cadenaoriginal);
InitOpenSSL;
key:=LoadPrivateKey(llaveprivada,'');
EVP_MD_CTX_init(@mdctx);
EVP_SignInit(@mdctx,EVP_sha1());
EVP_SignUpdate(@mdctx,@inbuf,StrLen(inbuf));
EVP_SignFinal(@mdctx,@outbuf,Len,key);
EVP_MD_CTX_cleanup(@mdctx);
EVP_PKEY_free(key);
FreeOpenSSL;
result := bintobase64(@outbuf,Len);
end;