Ambiente
- Padrão SQL Server 2016
- PHP 8.2
Fundo
Tenho criptografia em nível de coluna configurada e totalmente funcional para várias colunas. Meu banco de dados está interagindo com sucesso com clientes por meio de PHP.
Emitir
Não consigo fazer a criptografia em nível de coluna funcionar ao tentar armazenar um arquivo. Eu estava funcionando totalmente antes da criptografia com o seguinte código (simplificado):
PHP:
$filePath = $_FILES["file_ToUpload"]["tmp_name"];
// Read the file into a binary variable
$fileData = file_get_contents($filePath);
$fileData = unpack('H*hex', $fileData); // Convert binary data to hex
$fileData = $fileData['hex'];
// Prepare the SQL query
$query = "{CALL spUploadFile(?)}";
$params = array(
$fileData
);
$result = sqlsrv_query($conn, $query, $params);
O procedimento SQL:
ALTER PROCEDURE [dbo].[spUploadFile]
@FileData NVARCHAR(MAX)
AS
BEGIN
DECLARE @BinaryData VARBINARY(MAX) = CONVERT(VARBINARY(MAX), @FileData, 2); -- Convert hex string back to binary
INSERT INTO MyFiles (File_Data)
VALUES (@BinaryData)
END
Minhas tentativas
Sinto que tentei de tudo. Tentei passar o $filedata como binário no PHP. Aqui está o que achei que teria mais sucesso em meu procedimento SQL:
ALTER PROCEDURE [dbo].[spUploadFile]
@FileData NVARCHAR(MAX)
AS
BEGIN
OPEN SYMMETRIC KEY MY_SymmetricKey
DECRYPTION BY CERTIFICATE MY_ColumnEncryption;
Declare @EncryptedFileData VARBINARY(MAX) = ENCRYPTBYKEY(KEY_GUID('MY_SymmetricKey'), @FileData)
CLOSE SYMMETRIC KEY MY_SymmetricKey;
INSERT INTO MyFiles (File_Data)
VALUES (@EncryptedFileData)
END
No entanto, isso gera um erro: dados de string ou binários serão truncados. Eu também tentei:
Declare @EncryptedFileData VARBINARY(MAX) = ENCRYPTBYKEY(KEY_GUID('MY_SymmetricKey'), convert(varchar(MAX), @FileData))
Com os mesmos resultados. Um arquivo .txt funciona bem, mas a maioria dos outros não.
A tentativa de passar o arquivo como uma matriz de bytes também gerou um erro de truncamento:
PHP:
$filePath = $_FILES["file_ToUpload"]["tmp_name"];
// Read the file into a binary variable
$fileData = file_get_contents($filePath);
// Prepare the SQL query
$query = "{CALL spUploadFile(array($fileData, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY), SQLSRV_SQLTYPE_VARBINARY('max'))}";
$params = array(
$fileData
);
$result = sqlsrv_query($conn, $query, $params);
SQL:
ALTER PROCEDURE [dbo].[spUploadFile]
@FileData VARBINARY(MAX)
AS
BEGIN
OPEN SYMMETRIC KEY MY_SymmetricKey
DECRYPTION BY CERTIFICATE MY_ColumnEncryption;
Declare @EncryptedFileData VARBINARY(MAX) = ENCRYPTBYKEY(KEY_GUID('MY_SymmetricKey'), @FileData)
CLOSE SYMMETRIC KEY MY_SymmetricKey;
INSERT INTO MyFiles (File_Data)
VALUES (@EncryptedFileData)
END