Ver Mensaje Individual
  #437  
Antiguo 24-07-2012
aigartua aigartua is offline
Registrado
NULL
 
Registrado: jul 2012
Posts: 1
Reputación: 0
aigartua Va por buen camino
aportando algo mas

Bueno me he leido todo el hilo, yo programo en Lazarus, y hace unos años realicé esta solución, es algo muy parecido a lo que han dicho por aqui, solo les paso la función que utilicé para realizar la digestion completa tanto en md5 o sha1 y pasarla a base64, parametro msg la cadena orginal, tipo es para indicar el tipo de digestion MD5 o SHA1, la llave esta en formato DER:
Código Delphi [-]
// Función para obtener el sello del documento según los requerimientos
// y especificaciones del SAT
// Equivale a:
// openssl dgst -md5 -sign llave.pem cadenaoriginal.txt | openssl base64 -A > sello.txt
function TFinterfaz.sello(msg,tipo: widestring): string;
var
  Len: cardinal;
  mdctx: EVP_MD_CTX;
  inbuf, outbuf: array [0..4095] of char;
  key: puEVP_PKEY;
  bp: pBIO;
  pk: PuRSA;
  rkey: PuRSA;
  i: integer;
  s: string;

  // Función para encriptar a base64
  Function EncodeBase64(S : String) : String;
  Var
    S1,S2 : TStringStream;

  begin
    S1:=TStringStream.Create(S);
    Try
      S1.Position:=0;
      S2:=TStringStream.Create('');
      Try
        With TBase64EncodingStream.Create(S2) do
          Try
            CopyFrom(S1,S1.Size);
          Finally
            Free;
          end;
        Result:=S2.DataString;
      finally
        S2.Free;
      end;
   finally
     S1.Free;
   end;
  end;

  function TipoError: string;
  var
    ErrMsg: array [0..160] of char;
  begin
    ERR_error_string(ERR_get_error, @ErrMsg);
    result := StrPas(@ErrMsg);
  end;

begin
  // Inicializa la libreria de OpenSSL
  OpenSSL_add_all_algorithms;
  OpenSSL_add_all_ciphers;
  OpenSSL_add_all_digests;
  ERR_load_crypto_strings;
  // Leer la llave privada en formato DER con contraseña
  bp := BIO_new(BIO_s_file());
  BIO_read_filename(bp, Pchar(ruta+nomarchivo));
  pk := nil;
  rkey := PEM_read_bio_RSAPrivateKey(bp, pk, nil, PChar(passw));
  if rkey = nil then
    raise Exception.Create('Error en llave privada.' + TipoError);
  key := EVP_PKEY_new;
  EVP_PKEY_assign(key, EVP_PKEY_RSA, rkey);
  StrPCopy(inbuf, msg);
  if tipo = 'MD5' then
    // MD5
    EVP_SignInit(@mdctx, EVP_md5());
  if tipo = 'SHA1' then
    // SHA1
    EVP_SignInit(@mdctx, EVP_sha1());
  EVP_SignUpdate(@mdctx, @inbuf, StrLen(inbuf));
  EVP_SignFinal(@mdctx, @outbuf, Len, key);
  // Cierra la libreria y libera la memoria
  EVP_cleanup;
  // este procediemiento quita un byte porque regresaba el caracter final, quizá un #13 o #10 o \n
  // dado que el dll esta hecho en c pero por las prisas en su momento asi se quedó
  s:='';
  for i:=0 to len-1 do
    s:=s+outbuf[i];
  result:=EncodeBase64(S)
end;

espero que a alguien le sirva como a mi

Última edición por Casimiro Notevi fecha: 24-07-2012 a las 18:28:58. Razón: Poner etiquetas [delphi] [/delphi]
Responder Con Cita