Componente Delphi de cliente SFTP sgcIndy

· Componentes
Componente Delphi de cliente SFTP sgcIndy

La transferencia segura de archivos sigue siendo una pieza clave de la integración empresarial. Tanto si intercambias datos con partners bancarios, sincronizas archivos con servidores remotos o automatizas pipelines de despliegue, SFTP (SSH File Transfer Protocol) es el estándar de la industria para mover archivos de forma segura sobre redes no confiables.

El paquete sgcIndy incluye TIdSFTPClient — un componente Delphi nativo de cliente SFTP que funciona sobre SSH sin requerir herramientas externas de línea de comandos ni ejecutables de terceros. Soporta subida y descarga de archivos, gestión de directorios, enlaces simbólicos, atributos de archivo, seguimiento de progreso y algoritmos criptográficos modernos — todo mediante una API limpia y orientada a eventos.

Este artículo cubre todas las funcionalidades y proporciona código Delphi listo para usar para las operaciones SFTP más habituales.

Características principales

Transferencia de archivos
Sube y descarga archivos con tamaños de buffer configurables y eventos de progreso en tiempo real. Transfiere desde rutas de archivo o directamente desde objetos TStream.
Operaciones con directorios
Lista directorios con metadatos completos, crea y elimina directorios y resuelve rutas incluyendo enlaces simbólicos.
Criptografía moderna
Curve25519, ECDH, AES-GCM, claves Ed25519 y HMAC-SHA2. Negociación de algoritmos configurable para requisitos de cumplimiento.
Múltiples métodos de autenticación
Autenticación por contraseña, clave pública (RSA, ECDSA, Ed25519) y keyboard-interactive. Verificación de la host key con callbacks de fingerprint.
Atributos y permisos de archivo
Lee y modifica permisos, propietario, marcas de tiempo y tamaños de archivo. Soporte completo para bits de modo al estilo Unix y enlaces simbólicos.
Progreso y eventos
Sigue el progreso de la transferencia con bytes transferidos y tamaño total. Transferencias cancelables. Eventos de error, conexión y desconexión.

Inicio rápido — conectar y descargar un archivo

Un ejemplo mínimo que se conecta a un servidor remoto, descarga un archivo y se desconecta.

var
  oSFTP: TIdSFTPClient;
begin
  oSFTP := TIdSFTPClient.Create(nil);
  Try
    oSFTP.Host := 'sftp.example.com';
    oSFTP.Port := 22;
    oSFTP.Authentication.Username := 'deploy';
    oSFTP.Authentication.Password := 'secret';
    oSFTP.Connect;
    // Download a file
    oSFTP.Get('/data/report.csv', 'C:\local\report.csv');
    oSFTP.Disconnect;
  Finally
    oSFTP.Free;
  End;
end;

Autenticación

El componente soporta tres métodos de autenticación. Los tres están habilitados por defecto — el cliente y el servidor negocian automáticamente el más adecuado.

Autenticación por contraseña

oSFTP.Authentication.Username := 'admin';
oSFTP.Authentication.Password := 'secret';

Autenticación por clave pública

oSFTP.Authentication.Username := 'deploy';
oSFTP.Authentication.PrivateKeyFile := 'C:\keys\id_rsa';
oSFTP.Authentication.PublicKeyFile := 'C:\keys\id_rsa.pub';
oSFTP.Authentication.Passphrase := 'keypassphrase';

Verificación de la host key

Verifica la identidad del servidor inspeccionando el fingerprint de la host key en el evento OnSSHHostKey.

oSFTP.OnSSHHostKey := OnHostKey;
procedure TForm1.OnHostKey(Sender: TObject;
  const aHostKeyType, aFingerprint: string;
  var aAction: TIdSSHHostKeyVerification);
begin
  // Verify fingerprint against known hosts
  if aFingerprint = 'SHA256:xyzABC123...' then
    aAction := sshHostKeyAccept
  else
    aAction := sshHostKeyReject;
end;

Operaciones de archivo

Subida y descarga

// Upload a file
oSFTP.Put('C:\local\data.zip', '/uploads/data.zip');
// Download a file
oSFTP.Get('/reports/monthly.pdf', 'C:\local\monthly.pdf');
// Upload from a stream
oSFTP.Put(oMemoryStream, '/uploads/stream-data.bin');
// Download to a stream
oSFTP.Get('/data/export.csv', oFileStream);

Métodos de conveniencia con cadenas

// Read a remote file into a string
vContent := oSFTP.GetFileAsString('/config/settings.json');
// Write a string to a remote file
oSFTP.PutFileFromString('{"key":"value"}', '/config/settings.json');

Eliminar, renombrar y enlaces simbólicos

// Delete a remote file
oSFTP.Delete('/tmp/old-file.log');
// Rename / move a file
oSFTP.Rename('/data/temp.csv', '/data/final.csv');
// Create a symbolic link
oSFTP.Symlink('/data/final.csv', '/data/latest.csv');

Operaciones con directorios

// List directory contents with full metadata
var
  oItems: TIdSFTPDirectoryItems;
  i: Integer;
begin
  oItems := oSFTP.ListDirectory('/data');
  for i := 0 to Length(oItems) - 1 do
    WriteLn(oItems[i].Filename + ' - ' +
      IntToStr(oItems[i].Attrs.Size) + ' bytes');
end;
// Create and remove directories
oSFTP.MakeDirectory('/data/archive/2026');
oSFTP.RemoveDirectory('/data/temp');
// Get current working directory
vPath := oSFTP.GetCurrentDirectory;
// Resolve a path (follows symlinks, resolves . and ..)
vRealPath := oSFTP.RealPath('../data/../data/./file.txt');

Atributos e información de archivos

// Check existence
if oSFTP.FileExists('/data/report.csv') then
  WriteLn('File found');
if oSFTP.DirectoryExists('/data/archive') then
  WriteLn('Directory exists');
// Get file size
vSize := oSFTP.FileSize('/data/report.csv');
// Get full attributes (size, permissions, timestamps, UID/GID)
var
  oAttrs: TIdSFTPFileAttributes;
begin
  oAttrs := oSFTP.Stat('/data/report.csv');
  WriteLn('Size: ' + IntToStr(oAttrs.Size));
  WriteLn('Permissions: ' + IntToStr(oAttrs.Permissions));
end;

Progreso y cancelación de la transferencia

El evento OnSFTPProgress se dispara durante cada transferencia de archivo, proporcionando seguimiento en tiempo real con la capacidad de cancelar la transferencia en curso.

oSFTP.OnSFTPProgress := OnProgress;
procedure TForm1.OnProgress(Sender: TObject;
  const aFilename: string;
  aTransferred, aTotal: Int64;
  var Cancel: Boolean);
begin
  ProgressBar1.Max := aTotal;
  ProgressBar1.Position := aTransferred;
  Label1.Caption := Format('%s: %d / %d bytes',
    [aFilename, aTransferred, aTotal]);
  // Set Cancel := True to abort the transfer
  Cancel := FUserCancelled;
end;

Configuración de algoritmos criptográficos

El componente soporta estándares criptográficos modernos. Los valores por defecto son seguros, pero puedes personalizar la negociación de algoritmos por requisitos de cumplimiento o interoperabilidad.

Categoría Algoritmos soportados
Intercambio de claves Curve25519, ECDH (P-256, P-384, P-521), DH Group14/16
Host keys Ed25519, ECDSA (P-256, P-384, P-521), RSA (SHA2-256, SHA2-512)
Cifrados AES-256/192/128-CTR, AES-256/128-GCM
MACs HMAC-SHA2-256, HMAC-SHA2-512, HMAC-SHA1
// Restrict to only the strongest algorithms
oSFTP.Algorithms.Ciphers := 'aes256-gcm@openssh.com'
		,aes256-ctr';
oSFTP.Algorithms.KexAlgorithms := 'curve25519-sha256';
oSFTP.Algorithms.MACs := 'hmac-sha2-256,hmac-sha2-512';

Ejemplo completo

Un ejemplo listo para producción que se conecta con autenticación por clave pública, lista un directorio, descarga un archivo con seguimiento de progreso y gestiona errores.

uses
  IdSFTPClient, IdSSHClasses;
var
  oSFTP: TIdSFTPClient;
  oItems: TIdSFTPDirectoryItems;
  i: Integer;
begin
  oSFTP := TIdSFTPClient.Create(nil);
  Try
    // Connection
    oSFTP.Host := 'sftp.example.com';
    oSFTP.Port := 22;
    // Public key authentication
    oSFTP.Authentication.Username := 'deploy';
    oSFTP.Authentication.PrivateKeyFile := 'C:\keys\id_ed25519';
    // Events
    oSFTP.OnSFTPProgress := OnProgress;
    oSFTP.OnSFTPError := OnError;
    oSFTP.OnSSHHostKey := OnHostKey;
    // Connect
    oSFTP.Connect;
    // List remote directory
    oItems := oSFTP.ListDirectory('/data');
    for i := 0 to Length(oItems) - 1 do
      WriteLn(oItems[i].Filename);
    // Download file with progress
    oSFTP.Get('/data/backup.tar.gz', 'C:\backups\backup.tar.gz');
    // Disconnect
    oSFTP.Disconnect;
  Finally
    oSFTP.Free;
  End;
end;

Referencia de métodos

Método Descripción
GetDescarga un archivo a una ruta local o a TStream
PutSube un archivo desde una ruta local o TStream
DeleteElimina un archivo remoto
RenameRenombra o mueve un archivo remoto
ListDirectoryLista el contenido de un directorio con metadatos
MakeDirectoryCrea un directorio remoto
Stat / LStatObtiene los atributos del archivo (con/sin resolución de enlace simbólico)
FileExists / DirectoryExistsComprueba si un archivo o directorio existe
Symlink / ReadLinkCrea o lee enlaces simbólicos
GetFileAsString / PutFileFromStringMétodos de conveniencia basados en cadenas