PHPでは、ファイルの整合性を確保するために、 hash_update_streamを介して大きなファイルのハッシュ値を計算できます。データベースレコードファイルのハッシュと組み合わせることで、ファイルの整合性をその後に検証して、ファイルが改ざんされていないことを確認すると、ファイルのハッシュ値をすばやく比較できます。この記事では、このプロセスを実装する方法について詳しく説明します。
HASH_UPDATE_STREAM関数は、ファイルストリームからハッシュ値を計算するために使用されます。一度にファイルをメモリにロードする方法と比較して、ストリーミング処理を使用すると、メモリを効果的に保存できます。これは、大きなファイルの処理に特に適しています。
bool hash_update_stream ( resource $context , resource $handle [, int $length ] )
$コンテキスト: hash_init()によって初期化されたハッシュコンテキスト。
$ハンドル:有効なファイルハンドル。
$ length (オプション):一度に読み取られるバイト数、デフォルトは8192バイトです。
この関数は通常、 hash_init()およびhash_final()で使用されます。これは、最終計算されたハッシュ値を返すために使用されます。
hash_update_streamを使用することにより、ファイルのハッシュ計算結果をデータベースにストリーミングできます。検証するときは、ファイルのハッシュ値を再計算し、ファイルの整合性検証を実現するためにデータベースに保存されている値と比較するだけです。
プロセス全体の簡単な手順は次のとおりです。
ファイルをアップロードすると、ファイルのハッシュ値が計算され、データベースに保存されます。
ファイルを確認するとき、ハッシュはデータベースから読み取り、新しく計算されたハッシュと比較されます。
2つの一致する場合、ファイルが改ざんされていないことを意味します。それ以外の場合、ファイルの整合性が疑問視されます。
まず、ファイル情報とハッシュ値を記録するためのシンプルなデータベーステーブルを設計します。データベースには、構造が次のようなファイルテーブルが既にあると仮定します。
CREATE TABLE `files` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`filename` VARCHAR(255) NOT NULL,
`hash` CHAR(64) NOT NULL,
`uploaded_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
ファイル名はファイル名を保存し、ハッシュはファイルのハッシュ値を保存し、 upload_atをアップロード時間を記録します。
ユーザーがファイルをアップロードすると、ファイルストリームをhash_update_streamに渡してファイルのハッシュ値を計算し、ファイル名とハッシュ値をデータベースに保存します。
<?php
// ファイルのアップロード処理を想定します
if (isset($_FILES['file'])) {
// ファイルのアップロードに関する情報を取得します
$fileTmpPath = $_FILES['file']['tmp_name'];
$fileName = $_FILES['file']['name'];
// ハッシュ計算を初期化します
$hashContext = hash_init('sha256');
// ファイルストリームを開きます
$fileHandle = fopen($fileTmpPath, 'rb');
// ハッシュ値を計算します
while (!feof($fileHandle)) {
// ハッシュを更新します
hash_update_stream($hashContext, $fileHandle);
}
// 最終的なハッシュ値を取得します
$fileHash = hash_final($hashContext);
// ハッシュ値をデータベースに保存します
$db = new mysqli('localhost', 'root', '', 'file_db');
$stmt = $db->prepare("INSERT INTO files (filename, hash) VALUES (?, ?)");
$stmt->bind_param("ss", $fileName, $fileHash);
$stmt->execute();
// ファイルハンドルを閉じます
fclose($fileHandle);
}
?>
この例では、 hash_init()を使用してSha-256のハッシュコンテキストを初期化し、 hash_update_stream()を使用してアップロードされたファイルのハッシュ値を計算し、最後にhash_final()を使用してハッシュ値を取得し、データベースに保存します。
その後の検証プロセスでは、ファイル名に従ってデータベースから対応するハッシュ値を取得し、現在のファイルのハッシュ値と比較できます。
<?php
// ファイル検証処理を想定します
$fileNameToVerify = 'example_file.txt'; // ファイル名を検証する必要があると仮定します
$filePath = '/path/to/files/' . $fileNameToVerify;
// データベースでハッシュ値を取得します
$db = new mysqli('localhost', 'root', '', 'file_db');
$stmt = $db->prepare("SELECT hash FROM files WHERE filename = ?");
$stmt->bind_param("s", $fileNameToVerify);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
$storedHash = $row['hash'];
// 現在のファイルのハッシュ値を計算します
$hashContext = hash_init('sha256');
$fileHandle = fopen($filePath, 'rb');
while (!feof($fileHandle)) {
hash_update_stream($hashContext, $fileHandle);
}
$currentHash = hash_final($hashContext);
fclose($fileHandle);
// データベースのハッシュ値を現在計算されているハッシュ値と比較する
if ($currentHash === $storedHash) {
echo "ファイルの整合性検証が合格しました!";
} else {
echo "ファイルの整合性の確認に失敗しました!";
}
?>
検証中、最初にデータベースからファイルのハッシュ値を取得し、次にファイルのハッシュ値を再計算し、最後に比較します。 2つのハッシュが同じ場合、ファイルが変更されていないことを意味します。一貫性がない場合、ファイルに改ざんされている可能性があります。
hash_update_streamとdatabaseログファイルハッシュ値を組み合わせることにより、ファイルの整合性を効率的に検証できます。ファイルのアップロードであろうと後続の検証であろうと、ストリーミングハッシュ計算はメモリの使用量を効果的に削減でき、データベースのハッシュレコードはその後の検証のための信頼できるデータサポートを提供します。