Ejecute este experimento sobre cualquier libro "protegido con contraseña" que produzca su aplicación: cambie el nombre de .xlsx a .zip, ábralo con cualquier herramienta de archivos comprimidos y mire xl/worksheets/sheet1.xml. Si los valores de las celdas están allí en UTF-8 plano, el archivo no está cifrado, sin importar cuántos avisos de contraseña muestre Excel cuando alguien intenta editar una hoja. Hay equipos que entregan exportaciones de nómina durante años creyendo que la protección de hoja es cifrado, y la brecha solo aparece cuando una revisión de seguridad ejecuta exactamente esta prueba de renombrado.
HotXLS, una biblioteca nativa de hojas de cálculo para Delphi y C++Builder, traza una línea nítida entre ambas funciones: la protección de hojas y libros son restricciones de edición con un hash heredado deliberadamente débil, mientras que SaveAsEncrypted produce un paquete realmente cifrado con AES que no se abrirá sin la contraseña. Este artículo cubre qué escribe realmente esa llamada, la asimetría que debe contemplar en el diseño, HotXLS puede escribir archivos cifrados pero no leerlos de vuelta, y dónde difiere la ruta XLS heredada.
La prueba de renombrado: por qué la protección de hoja no es cifrado
Los métodos Protect de las hojas y ProtectWorkbook del libro almacenan un hash de 4 dígitos hexadecimales de la contraseña, el algoritmo heredado que las especificaciones OOXML y BIFF recibieron de Excel de los años noventa. Su propósito es detener ediciones accidentales, y la documentación del formato nunca afirma más. El paquete en sí sigue siendo un zip ordinario legible; los datos de celdas, fórmulas y cadenas están todos en XML claro. Peor aún, el valor predeterminado de OOXML es Locked=True en todas las celdas, así que llamar a Protect sin desbloquear un área de entrada produce una hoja completamente congelada que aun así no es confidencial.
La protección tiene usos legítimos, como guiar a los usuarios hacia rangos editables o estabilizar diseños para impresión, todo cubierto en nuestro artículo sobre protección de hojas y configuración de página, pero en el momento en que el requisito dice confidencialidad, la única API relevante es SaveAsEncrypted.
Qué escribe realmente SaveAsEncrypted
La implementación sigue ECMA-376 Standard Encryption según [MS-OFFCRYPTO] sección 2.3.4. La contraseña pasa por 50,000 iteraciones de SHA-1 para derivar una clave AES-128; un bloque verificador cifrado con AES-128 ECB permite que un consumidor confirme la contraseña antes de descifrar nada; y todo el paquete del libro se cifra con AES-128 en modo CBC. El resultado no es un zip, sino un archivo compuesto OLE que contiene los flujos EncryptionInfo, EncryptedPackage y DataSpaces, por eso la prueba de renombrado ahora falla, como debe ser: no hay directorio xl/ que una herramienta de archivos comprimidos pueda mostrar. Excel 2007 y posteriores abren el archivo con nada más que la contraseña, y LibreOffice actual también maneja Standard Encryption.
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
rc: Integer;
begin
Book := TXLSXWorkbook.Create;
try
Sheet := Book.Sheets.Add('Payroll');
Sheet.Cells[1, 1].Value := 'Employee';
Sheet.Cells[1, 2].Value := 'Net pay';
Sheet.Cells[2, 1].Value := 'A. Garcia';
Sheet.Cells[2, 2].Value := 4815.16;
rc := Book.SaveAsEncrypted('payroll-2026-06.xlsx', PasswordFromVault);
if rc <> 1 then
raise Exception.CreateFmt('Encrypted save failed (rc=%d)', [rc]);
finally
Book.Free;
end;
end;
Trate la variable de contraseña con el mismo cuidado que una cadena de conexión: obténgala de una bóveda o de un servicio de secretos generados en el último momento, nunca la registre en logs y nunca la escriba dentro del propio libro. La comprobación del código de retorno tampoco es ceremonia opcional: un guardado cifrado que falla a mitad de camino debe abortar la entrega, porque el fallback de enviar una copia sin cifrar es exactamente el incidente que esta función existe para prevenir.
También existe una comprobación de aceptación barata y verificable por máquina: llame a CanReadEncrypted sobre el archivo que acaba de escribir. Responde true solo cuando la salida realmente es un contenedor de cifrado, así que afirmarlo después de cada guardado cifrado detecta la peor regresión, una ruta de código que cayó silenciosamente a un SaveAs plano, en el momento en que ocurre y no en la bandeja de entrada de un cliente. El árbitro final sigue siendo una apertura manual en Excel con la contraseña prevista durante las pruebas de lanzamiento.
Solo escritura por diseño: manejo de EXlsxEncryptionNotImplemented
Esta es la asimetría que debe dar forma a la arquitectura de su canalización: HotXLS cifra al guardar, pero no descifra al abrir. OpenEncrypted lanza EXlsxEncryptionNotImplemented cuando apunta a un paquete realmente cifrado; sobre un libro plano simplemente cae a un Open normal. El sondeo complementario CanReadEncrypted detecta de forma económica el contenedor OLE de cifrado, para que el código de recepción pueda enrutar esos archivos sin disparar la excepción:
var
Book: TXLSXWorkbook;
begin
Book := TXLSXWorkbook.Create;
try
if Book.CanReadEncrypted(FileName) then
begin
// Encrypted container: HotXLS cannot decrypt it.
Writeln(FileName + ': needs manual decryption in Excel first');
Exit;
end;
try
Book.OpenEncrypted(FileName, ''); // plain files fall through to Open
Writeln(FileName + ': opened, ' + IntToStr(Book.Sheets.Count) + ' sheet(s)');
except
on EXlsxEncryptionNotImplemented do
Writeln(FileName + ': encrypted - routed to manual queue');
end;
finally
Book.Free;
end;
end;
La consecuencia arquitectónica es clara: cifre al borde de entrega, al final. Mantenga el maestro en texto claro dentro de su perímetro de confianza, base de datos, almacén documental o recurso compartido con control de acceso, y produzca la copia cifrada como último paso antes de que el archivo salga. Una canalización que archiva solo la salida cifrada se ha bloqueado a sí misma fuera de sus propios datos, porque ninguna etapa posterior del mismo sistema puede reabrir esos archivos. Si un proceso HotXLS posterior debe consumir otra vez el libro, entréguele el maestro en texto claro, no el artefacto de entrega.
AES-128 Standard Encryption y la línea de cumplimiento AES-256
El cifrado de archivos de Office tiene dos generaciones. Standard Encryption, lo que escribe HotXLS, usa AES-128 con derivación de clave SHA-1. Agile Encryption, introducido después, sube a AES-256 con SHA-512 y un contenedor de claves descrito en XML diferente. Ambos se abren de forma transparente en Excel, y AES-128 sigue siendo computacionalmente sólido para proteger archivos en tránsito hacia un cliente.
La distinción importa el día en que un cuestionario de seguridad pregunte por "cifrado AES-256 de archivos en reposo". Standard Encryption no satisface ese requisito, sin importar qué tan fuerte sea la contraseña, y ningún parámetro de SaveAsEncrypted cambia el algoritmo. Declare por adelantado el perfil real en su documentación de seguridad: AES-128, ECMA-376 Standard Encryption, derivación de clave SHA-1 con 50,000 iteraciones. Una afirmación precisa que pasa revisión vale más que una optimista que falla en una auditoría.
La ruta XLS heredada: RC4 al escribir, RC4 y XOR al leer
La fachada BIFF tiene la forma opuesta: su cifrado es más antiguo y más débil, pero el ciclo de ida y vuelta está completo. Establecer EncryptionPassword antes de SaveAs produce un .xls cifrado con RC4, el mecanismo BIFF FilePass, y Open con un parámetro de contraseña lee los tres esquemas heredados: RC4, RC4 CryptoAPI y la antigua ofuscación XOR:
var
Writer, Reader: IXLSWorkbook; // interface refs: no manual Free
begin
Writer := TXLSWorkbook.Create;
Writer.Sheets.Add.Cells.Item[1, 1].Value := 'Confidential';
Writer.EncryptionPassword := 'S3cret!';
Writer.SaveAs('confidential.xls');
Reader := TXLSWorkbook.Create;
if Reader.Open('confidential.xls', 'S3cret!') > 0 then
Writeln(Reader.Sheets[1].Cells.Item[1, 1].Value); // Entries are 1-based
end;
RC4 es criptografía obsoleta y nunca debe proteger datos que importan hoy; su valor es la interoperabilidad con sistemas que todavía intercambian .xls. La capacidad de lectura, sin embargo, sí es útil en canalizaciones de migración: los archivos heredados protegidos con contraseña pueden abrirse con Open(FileName, Password), llevarse al modelo OOXML y volver a protegerse con la ruta AES, una actualización unidireccional que funciona completamente sin Excel. Para entregas cifradas de alto volumen, las notas de rendimiento del lado de guardado en nuestro artículo sobre escritura en streaming para trabajos por lotes de servidor aplican a la fase de construcción de contenido antes del cifrado.
Preguntas frecuentes
¿HotXLS puede reabrir un XLSX cifrado que creó?
No. La ruta de escritura está completa y es compatible con Excel, pero OpenEncrypted lanza EXlsxEncryptionNotImplemented para cualquier paquete cifrado, incluida la propia salida de HotXLS. Verifique las entregas abriéndolas en Excel con la contraseña prevista y conserve un maestro en texto claro para cualquier proceso que deba volver a leer los datos.
¿Una contraseña perdida puede recuperarse desde el archivo?
No por diseño. La derivación de clave de 50,000 iteraciones existe para encarecer los intentos de adivinación, y no hay depósito de recuperación dentro del archivo. La custodia de contraseñas es responsabilidad de su aplicación: genere, entregue y almacene contraseñas con la misma disciplina de gestión de secretos que usa para credenciales.
¿Debo combinar protección de hoja con cifrado?
Resuelven problemas distintos y se apilan limpiamente: el cifrado controla quién puede abrir el archivo, la protección controla qué puede editar una vez dentro. Una entrega de nómina podría cifrar el paquete y también bloquear celdas de fórmula para que el destinatario pueda filtrar, pero no alterar cálculos. Nunca deje que la presencia de protección sustituya al cifrado en un requisito de confidencialidad.
El cifrado real de archivos es una llamada en HotXLS, y la disciplina está en todo lo que rodea la llamada: custodia de contraseñas, el límite de solo escritura y una declaración precisa del algoritmo. SaveAsEncrypted y el ciclo heredado se incluyen en HotXLS Component, ejecutándose de forma nativa en procesos Delphi y C++Builder sin automatización de Excel.