ویژگی تصویر

تابع sha1_file() در PHP

  /  PHP   /  تابع sha1_file() در PHP
بنر تبلیغاتی الف
آموزش PHP

تابع sha1_file() در PHP برای محاسبه مقدار هش SHA-1 از محتویات یک فایل به کار می‌رود. این تابع در بسیاری از سناریوها مانند بررسی یکپارچگی فایل‌ها، ذخیره مقدار هش برای تشخیص تغییرات یا مقایسه سریع محتوا مفید است. در این مقاله به صورت عملی، مثال‌های کاربردی، محدودیت‌ها و جایگزین‌های امن‌تر را بررسی می‌کنیم.

سینتکس و مقدار بازگشتی

سینتکس:

sha1_file(string $filename, bool $binary = false): string|false

توضیح:

  • $filename: مسیر فایل روی سیستم یا URL در صورت فعال بودن allow_url_fopen.
  • $binary: اگر true باشد خروجی به‌صورت رشته باینری (20 بایت) بازگردانده می‌شود؛ در غیر این صورت مقدار هگزادسیمال 40 نویسه‌ای (پیش‌فرض).
  • در صورت موفقیت مقدار هش برگردانده می‌شود و در صورت خطا false و هشدار (E_WARNING) صادر می‌گردد.

مثال پایه‌ای

<?php
$file = '/path/to/file.zip';
$hash = sha1_file($file);
if ($hash === false) {
    echo "Unable to read file";
} else {
    echo "SHA-1: " . $hash . "n";
}
?>

این قطعه کد مسیر فایل را می‌گیرد و اگر خواندن موفقیت‌آمیز باشد، مقدار هش SHA-1 را به‌صورت رشته هگزادسیمال نمایش می‌دهد. در صورت بروز مشکل، پیام خطا داده می‌شود.

مثال: استفاده در بارگذاری فایل (Upload) برای بررسی یکپارچگی

<?php
// فرض: کاربر فایلی را آپلود کرده و ما می‌خواهیم هش سمت سرور را با هشی که کاربر اعلام کرده مقایسه کنیم.
$uploaded = $_FILES['file']['tmp_name'];
$clientHash = $_POST['sha1']; // هش ارسال شده از سمت کاربر
$serverHash = sha1_file($uploaded);

if ($serverHash === false) {
    die('Error reading uploaded file');
}

if (hash_equals($serverHash, $clientHash)) {
    echo 'File integrity OK.';
} else {
    echo 'Mismatch detected.';
}
?>

در این مثال از تابع امن hash_equals() برای جلوگیری از حملات زمان‌بری (timing attacks) هنگام مقایسه رشته‌های هش استفاده شده است. این بهترین روش برای مقایسه هش‌ها است و از مقایسه ساده با == یا === امن‌تر است.

خروجی باینری و Base64

<?php
$raw = sha1_file('bigfile.bin', true); // خروجی باینری 20 بایتی
$base64 = base64_encode($raw);
echo $base64;
?>

در این قطعه، با تنظیم پارامتر دوم روی true مقدار باینری خام دریافت می‌کنیم و برای منتقل کردن یا ذخیره‌سازی فشرده آن را به Base64 تبدیل می‌کنیم. این روش حافظه کمتری نسبت به خواندن کل فایل در متغیر دارد، اما در نهایت sha1_file خودش فایل را به صورت جریانی (streamed) پردازش می‌کند.

مقایسه با hash_file و الگوریتم‌های قوی‌تر

SHA-1 در برابر حملات تصادم (collision) ضعیف شده و برای کاربردهای امنیتی مانند امضای دیجیتال توصیه نمی‌شود. به‌عنوان جایگزین از توابعی مانند hash_file(‘sha256’, …) یا الگوریتم‌های قوی‌تر استفاده کنید.

<?php
$sha256 = hash_file('sha256', '/path/to/file.zip');
echo 'SHA-256: ' . $sha256;
?>

این نمونه نشان می‌دهد چگونه با یک تابع عمومی‌تر (hash_file) می‌توان الگوریتم دلخواه را انتخاب کرد. SHA-256 به مراتب مقاوم‌تر در برابر برخوردهاست و برای بیشتر سناریوهای امنیتی مناسب‌تر است.

وقایع و نکات عملکردی

  • sha1_file فایل را به صورت جریانی می‌خواند؛ در نتیجه نسبت به خواندن کل فایل با file_get_contents حافظه کمتری مصرف می‌کند و برای فایل‌های بزرگ مناسب است.
  • اگر allow_url_fopen فعال باشد می‌توان از URL نیز استفاده کرد، اما این کار می‌تواند کند و ناامن باشد؛ بهتر است فایل را ابتدا دانلود یا تایید کنید.
  • برای پروفایلینگ و اندازه‌گیری سرعت، تابع‌های native مانند sha1_file معمولاً سریع‌تر از پیاده‌سازی‌های مبتنی بر فایل خوانده شده در PHP هستند.

مثال پیشرفته: استفاده از hash_init برای کنترل بهتر

<?php
// در صورتی که بخواهید چندین الگوریتم یا آپدیت تدریجی داشته باشید:
$ctx = hash_init('sha256');
$handle = fopen('/path/to/large.file', 'rb');
while (!feof($handle)) {
    $data = fread($handle, 8192);
    hash_update($ctx, $data);
}
fclose($handle);
$final = hash_final($ctx);
echo $final;
?>

این روش زمانی مفید است که بخواهید پردازش فایل را کنترل کنید (مثلاً خواندن بلوک‌ بلوک، کار با فایل شبکه یا آپدیت هم‌زمان چند هش). همچنین امکان استفاده از الگوریتم‌های مختلف یا محاسبه همزمان چند هش وجود دارد.

جدول مقایسه: sha1_file در برابر alternatives

ویژگیsha1_file()hash_file(‘sha256’)
امنیت (برخورد)ضعیف‌ترقوی‌تر
طول خروجی40 نویسه هگز (یا 20 بایت باینری)64 نویسه هگز (یا 32 بایت باینری)
کاربری متداولبررسی یکپارچگی ساده، تطبیق سریعامنیت و کاربردهای حساس

نکات امنیتی و بهترین روش‌ها

  • برای کاربردهای حساس مانند امضا، تایید هویت یا ذخیره گذرواژه از SHA-1 استفاده نکنید. برای گذرواژه‌ها از الگوریتم‌های مخصوص نظیر password_hash استفاده کنید.
  • هنگام مقایسه هش‌ها از hash_equals استفاده کنید تا از مشکلات timing-attack جلوگیری شود.
  • اگر نیاز به قابلیت‌های حفاظتی بیشتر دارید، از SHA-256 یا SHA-3 و توابع امن کتابخانه‌ای استفاده کنید.
  • خروجی باینری را هنگام ذخیره یا انتقال به صورت Base64 یا از طریق پایگاه‌داده باینری (BLOB) مدیریت کنید.

موارد استفاده واقعی

  • بررسی یکپارچگی فایل‌های دانلود شده یا بکاپ‌ها
  • شناسایی سریع تغییرات فایل در سیستم‌های توزیع‌شده
  • ایجاد شناسه‌های تقریبی برای کش کردن فایل‌ها (cache keys)
  • مقایسه فایل‌های آپلود شده با نمونه‌های مرجع

تابع sha1_file() ابزار ساده و سریع برای محاسبه هش SHA-1 از فایل‌هاست، اما باید هنگام به‌کارگیری در سناریوهای امنیتی دقت کرد و در صورت نیاز از الگوریتم‌های قوی‌تر یا مکانیزم‌های امن‌تر استفاده نمود.

در صورت نیاز می‌توان مثال‌های بیشتری حول بهینه‌سازی‌ها، خواندن از استریم‌های شبکه یا ترکیب همزمان چند هش مطرح کرد.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: