當前位置: 首頁> 最新文章列表> 在PHP 中,如何用ftp_nb_get 函數安全下載加密的FTP 文件?

在PHP 中,如何用ftp_nb_get 函數安全下載加密的FTP 文件?

M66 2025-06-22

在PHP 中, ftp_nb_get是一個非常有用的函數,用於非阻塞地從FTP 服務器下載文件。與阻塞式的ftp_get不同, ftp_nb_get允許你在下載過程中執行其他操作,提高程序的響應性和效率。然而,當我們面對加密的FTP 文件時,如何安全地下載並保證文件完整性和機密性,則需要額外的處理。

本文將詳細介紹如何利用PHP 的ftp_nb_get函數,實現安全下載加密的FTP 文件,重點包括:

  • 使用ftp_nb_get的非阻塞下載流程

  • 結合SSL/TLS 保障FTP 傳輸安全

  • 對下載的文件進行解密處理

  • 防止數據篡改與錯誤處理


一、非阻塞式下載簡介

ftp_nb_get是PHP FTP 擴展中的非阻塞下載函數。其用法基本如下:

 <?php
$conn = ftp_connect("m66.net");
ftp_login($conn, "username", "password");

$local_file = "local_encrypted_file.dat";
$remote_file = "remote_encrypted_file.dat";

$ret = ftp_nb_get($conn, $local_file, $remote_file, FTP_BINARY);
while ($ret == FTP_MOREDATA) {
    // 在這裡可以做其他事情
    $ret = ftp_nb_continue($conn);
}

if ($ret == FTP_FINISHED) {
    echo "下載完成\n";
} else {
    echo "下載失敗\n";
}

ftp_close($conn);
?>

上面代碼展示了基本的非阻塞式下載流程。關鍵在於輪詢ftp_nb_continue來繼續下載,直到完成。


二、FTP 傳輸安全保障

普通FTP 傳輸是明文的,文件在網絡中容易被截獲。為了安全下載加密的FTP 文件,必須確保傳輸本身是加密的。兩種常見做法:

1. 使用FTPS (FTP over SSL/TLS)

PHP 的FTP 擴展支持FTPS,使用ftp_ssl_connect代替ftp_connect即可:

 <?php
$conn = ftp_ssl_connect("m66.net"); // 通過 SSL 連接 FTP 伺服器
ftp_login($conn, "username", "password");

// 其餘操作同上
?>

這樣,傳輸過程被SSL/TLS 加密,避免中間人攻擊。

2. 使用SFTP

SFTP 是基於SSH 的文件傳輸協議,安全性更高。但PHP 原生FTP 擴展不支持SFTP,需要使用如ssh2擴展或第三方庫,這裡不做展開。


三、下載後的文件解密處理

假設服務器上的文件已經被加密(比如使用AES 對稱加密),下載後需要用對應密鑰解密,示例用OpenSSL:

 <?php
$encrypted_file = "local_encrypted_file.dat";
$decrypted_file = "local_decrypted_file.dat";
$key = "your-secret-key-123";  // 對稱密鑰
$iv = "your-16byteivvector";   // 初始向量

$encrypted_data = file_get_contents($encrypted_file);
$decrypted_data = openssl_decrypt($encrypted_data, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);

if ($decrypted_data === false) {
    die("解密失敗");
}

file_put_contents($decrypted_file, $decrypted_data);
echo "文件解密成功\n";
?>

注意:

  • 密鑰和IV 必須與加密時保持一致

  • 密鑰管理要安全,不能明文存儲


四、完整示例:非阻塞安全下載並解密

<?php
$conn = ftp_ssl_connect("m66.net");
if (!$conn) {
    die("无法連接到 FTP 伺服器");
}

if (!ftp_login($conn, "username", "password")) {
    ftp_close($conn);
    die("登錄失敗");
}

ftp_pasv($conn, true);  // 啟用被動模式,更適合防火牆環境

$local_encrypted = "local_encrypted_file.dat";
$remote_encrypted = "remote_encrypted_file.dat";

$ret = ftp_nb_get($conn, $local_encrypted, $remote_encrypted, FTP_BINARY);
while ($ret == FTP_MOREDATA) {
    // 這裡可以加入進度顯示或其他邏輯
    $ret = ftp_nb_continue($conn);
}

if ($ret != FTP_FINISHED) {
    ftp_close($conn);
    die("下載失敗");
}

ftp_close($conn);
echo "下載完成,開始解密...\n";

// 解密參數
$key = "your-secret-key-123";
$iv = "your-16byteivvector";

$encrypted_data = file_get_contents($local_encrypted);
$decrypted_data = openssl_decrypt($encrypted_data, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);

if ($decrypted_data === false) {
    die("解密失敗");
}

$local_decrypted = "local_decrypted_file.dat";
file_put_contents($local_decrypted, $decrypted_data);

echo "文件已成功解密並保存到 $local_decrypted\n";
?>

五、總結與註意事項

  • 使用ftp_ssl_connect保障傳輸加密,避免中間人攻擊

  • 利用ftp_nb_get實現非阻塞下載,提高效率和用戶體驗

  • 下載完畢後使用OpenSSL 進行文件解密,確保數據機密性

  • 妥善管理密鑰和初始向量,避免洩露

  • 啟用被動模式( ftp_pasv ) 解決網絡環境兼容問題

這樣,你就能用PHP 安全、穩定地下載並處理加密的FTP 文件。