O HotXLS grava um bloco dataIntegrity conforme a especificação em pacotes XLSX com criptografia Agile e o verifica na abertura. O HMAC-SHA-512 cobre o stream EncryptedPackage completo, incluindo seu prefixo StreamSize de oito bytes, e é verificado sobre o texto cifrado antes que qualquer segmento seja decifrado, de modo que uma senha errada ou um pacote modificado é detectado em vez de ser decifrado em lixo
Criptografia sem integridade é meia resposta, e os formatos de arquivo do Office tornam essa lacuna fácil de ignorar porque a criptografia parece muito completa vista de fora. Entender o que cada camada promete é o que mantém uma revisão de segurança curta
O que uma pasta de trabalho criptografada realmente promete?
A criptografia Agile, definida em [MS-OFFCRYPTO], oferece confidencialidade por meio de AES em modo CBC com uma chave derivada de um hash de senha SHA-512 iterado. Confidencialidade é toda a promessa dessa construção. CBC não é um modo autenticado: ele não diz nada sobre se o texto cifrado que você está decifrando é o texto cifrado que foi originalmente gravado
A consequência prática é específica. Inverta bits em um pacote criptografado e o CBC vai decifrá-los alegremente em um texto plano diferente. Normalmente você vai receber um erro de parsing de ZIP em algum ponto adiante, porque um stream deflate corrompido raramente sobrevive, mas "normalmente" carrega muito peso nessa frase, e um erro de parser mais adiante é um péssimo lugar para descobrir que um arquivo foi modificado. O elemento dataIntegrity existe para responder essa pergunta diretamente, antes da decifragem, com um MAC sobre os bytes exatos
Como a verificação funciona, e em qual ordem
A ordem é a parte interessante. O HotXLS deriva a chave intermediária a partir da senha, decifra a chave HMAC e o valor HMAC criptografados a partir dos atributos de dataIntegrity usando IVs derivados de chave de bloco, calcula o HMAC-SHA-512 sobre o pacote criptografado tal como armazenado, e compara. Somente então a decifragem dos segmentos começa
Verificar o MAC sobre o texto cifrado, em vez do texto plano, é a disciplina padrão de encrypt-then-MAC, e é isso que torna a verificação significativa: um pacote adulterado é rejeitado sem que nenhum byte controlado pelo atacante passe pelo caminho de decifragem e inflate. As duas comparações no caminho de abertura, o hash verificador de senha e o valor HMAC, acumulam diferenças com XOR e OR ao longo de todo o digest, em vez de retornar antecipadamente no primeiro byte divergente, de modo que nenhuma delas vaza a posição de um byte por meio de timing
var
Book: TXLSXWorkbook;
begin
Book := TXLSXWorkbook.Create;
try
// Funciona para arquivos simples, com criptografia Standard e com criptografia Agile
if Book.OpenEncrypted('incoming.xlsx', PasswordFromVault) = 1 then
ProcessWorkbook(Book)
else
// Senha errada, ou um pacote cujo HMAC de dataIntegrity não corresponde
Quarantine('incoming.xlsx');
except
on E: Exception do
Quarantine('incoming.xlsx: ' + E.Message);
end;
Book.Free;
end;
Do lado da escrita, nada muda no seu código. SaveAsEncrypted emite o bloco automaticamente, e os salts, a entrada do verificador e a chave HMAC vêm de CryptGenRandom. Se essa chamada falhar, o HotXLS gera uma exceção em vez de recorrer a uma fonte mais fraca. Um CSPRNG fail-closed não é paranoia; um downgrade silencioso para uma fonte aleatória previsível produz arquivos que parecem criptografados, passam em todo teste funcional e não valem nada
Por que arquivos sem o bloco ainda abrem?
Porque um grande número de pastas de trabalho com criptografia Agile em circulação foi gravado por produtores que omitem dataIntegrity por completo, e rejeitá-las quebraria muito mais trabalho legítimo do que protegeria. O HotXLS trata a integridade como presente apenas quando os dois atributos, a chave HMAC criptografada e o valor HMAC criptografado, estão presentes e bem formados. Caso contrário, a verificação é ignorada e o arquivo abre como antes
Essa é uma decisão de compatibilidade com uma consequência de segurança que você deve nomear explicitamente no seu próprio modelo de ameaças: a ausência do bloco não pode ser distinguida de um atacante que o removeu, porque os atributos ficam fora do MAC que eles carregariam. Se você controla as duas pontas de um pipeline, trate um bloco ausente como uma falha de política em nível de aplicação. Se você está recebendo arquivos vindos do mundo, trate a verificação pelo que ela é, um sinal valioso quando presente e nenhum sinal quando ausente
Senha para modificar é uma convenção, não uma barreira
Pastas de trabalho XLS clássicas suportam um mecanismo separado que é rotineiramente confundido com criptografia: a reserva de gravação, o prompt "senha para modificar" do Excel. O HotXLS expõe esse mecanismo por meio de SetModifyPassword, que recebe a senha, um flag de recomendação de somente leitura e o nome do usuário que fez a reserva, e relata o estado por meio de IsWriteReserved. Passar uma senha vazia limpa a reserva
O que é gravado é um par de registros WRITEPROT e FILESHARING carregando o flag de recomendação de somente leitura, um hash de senha legado de 16 bits e o nome do usuário como uma string Unicode BIFF8. Esse hash de 16 bits é um checksum, não um digest criptográfico, e o conteúdo do documento não é criptografado de forma alguma. Qualquer um que abra o arquivo com qualquer outra ferramenta lê tudo. A função real desse recurso é coordenação: ela diz à próxima pessoa que alguém considera esse arquivo seu para editar, na mesma categoria dos controles em nível de planilha abordados em proteção de planilha e opções allow em XLSX
var
Book: IXLSWorkbook; // contado por interface: não chame Free
begin
Book := TXLSWorkbook.Create;
if Book.Open('shared-model.xls') = 1 then
begin
// Recomenda somente leitura, reservado pelo serviço de relatórios
Book.SetModifyPassword('edit-me', True, 'Reporting Service');
if Book.IsWriteReserved then
Book.SaveAs('shared-model.xls', xlExcel97);
end;
end;
Use cada camada para aquilo em que ela é boa. A confidencialidade real vem de SaveAsEncrypted com uma senha que ninguém fora do público-alvo possui, o que produz a saída AES-256 descrita em saída XLSX protegida por AES. A reserva de gravação entra por cima quando a pasta de trabalho é um artefato de edição compartilhada e você quer que o Excel pergunte antes que alguém sobrescreva
O que verificar em um pipeline de entrada não confiável
A verificação de integridade protege o payload criptografado, não o contêiner ao redor dele. Um arquivo XLSX é um arquivo ZIP, e a estrutura do arquivo é analisada antes que qualquer lógica de criptografia seja executada, então a validação em nível de contêiner deve vir primeiro na cadeia; os modos de falha específicos são abordados em validação de end-of-central-directory de ZIP para XLSX não confiável. Depois disso, trate uma falha de integridade e uma senha errada como o mesmo evento operacional, porque do seu lado elas são indistinguíveis por design, e ambas significam que o arquivo não pode ser considerado confiável em relação ao que o remetente pensa que ele é
Registre em log quais arquivos sequer carregavam um bloco dataIntegrity. Ao longo de alguns milhares de documentos, essa estatística diz algo útil sobre as ferramentas dos seus remetentes, e transforma uma verificação por arquivo em uma observação de nível de frota sobre a qual você pode agir
O HotXLS lê e grava XLS, XLSX e ODS a partir de Delphi e C++Builder sem exigir instalação do Excel, implementando os caminhos de criptografia Standard e Agile do [MS-OFFCRYPTO] em Pascal. As APIs de criptografia, proteção e pasta de trabalho estão documentadas na página do componente HotXLS Delphi para planilhas