文件打包与加密传输
概述
数据在传输前需要进行打包压缩和加密处理,以确保传输效率和数据安全。本文详细介绍使用 bash 工具链实现文件打包、加密传输、分卷传输和断点续传。
核心理念
- 先压缩后加密:提高传输效率同时保证安全
- 完整性校验:使用校验和验证数据完整性
- 分卷传输:大文件分块传输,支持断点续传
- 密钥管理:安全的密钥生成和分发
1. tar + 加密打包
pack_and_encrypt() {
local input="$1" output="$2" password="$3"
local temp_file
temp_file=$(mktemp /tmp/pack_XXXXXX.tar.gz)
# 打包压缩
tar czf "$temp_file" -C "$(dirname "$input")" "$(basename "$input")" 2>/dev/null
# openssl 加密
openssl enc -aes-256-cbc -salt -pbkdf2 \
-in "$temp_file" \
-out "$output" \
-pass "pass:$password" 2>/dev/null
local checksum
checksum=$(sha256sum "$output" | awk '{print $1}')
echo "$checksum" > "${output}.sha256"
rm -f "$temp_file"
echo "[+] 已加密: $output (SHA256: ${checksum:0:16}...)"
}
unpack_and_decrypt() {
local input="$1" output_dir="$2" password="$3"
local temp_file
temp_file=$(mktemp /tmp/unpack_XXXXXX.tar.gz)
openssl enc -aes-256-cbc -d -salt -pbkdf2 \
-in "$input" \
-out "$temp_file" \
-pass "pass:$password" 2>/dev/null
mkdir -p "$output_dir"
tar xzf "$temp_file" -C "$output_dir" 2>/dev/null
rm -f "$temp_file"
echo "[+] 已解压到: $output_dir"
}
verify_integrity() {
local file="$1"
local checksum_file="${1}.sha256"
[[ ! -f "$checksum_file" ]] && { echo "[-] 校验文件不存在"; return 1; }
local expected actual
expected=$(cat "$checksum_file")
actual=$(sha256sum "$file" | awk '{print $1}')
if [[ "$expected" == "$actual" ]]; then
echo "[+] 完整性验证通过"
return 0
else
echo "[-] 完整性验证失败"
return 1
fi
}1.2 GPG 加密传输
gpg_encrypt() {
local file="$1" recipient="$2" output="${1}.gpg"
gpg --encrypt --recipient "$recipient" --output "$output" "$file"
echo "[+] GPG 加密完成: $output"
}
gpg_symmetric_encrypt() {
local file="$1" password="$2" output="${1}.gpg"
echo "$password" | gpg --batch --yes --passphrase-fd 0 \
--symmetric --cipher-algo AES256 \
--output "$output" "$file"
echo "[+] 对称加密完成: $output"
}2. openssl 加密传输
openssl_transfer() {
local file="$1" remote="$2" remote_path="$3" password="$4"
echo "[*] 加密传输: $file -> $remote:$remote_path"
cat "$file" | \
openssl enc -aes-256-cbc -salt -pbkdf2 -pass "pass:$password" | \
ssh "$remote" "cat > ${remote_path}.enc"
sha256sum "$file" | ssh "$remote" "cat > ${remote_path}.sha256"
echo "[+] 传输完成"
}
openssl_receive() {
local remote="$1" remote_file="$2" local_file="$3" password="$4"
ssh "$remote" "cat $remote_file" | \
openssl enc -aes-256-cbc -d -salt -pbkdf2 -pass "pass:$password" > "$local_file"
echo "[+] 接收完成: $local_file"
}
generate_openssl_keys() {
local output_dir="${1:-/tmp/keys}"
mkdir -p "$output_dir"
openssl genrsa -out "$output_dir/private.pem" 2048 2>/dev/null
openssl rsa -in "$output_dir/private.pem" \
-pubout -out "$output_dir/public.pem" 2>/dev/null
echo "[+] 密钥对已生成: $output_dir"
}3. SCP/SFTP 安全传输
scp_transfer() {
local file="$1" remote="$2" remote_path="$3"
echo "[*] SCP 传输: $file -> $remote:$remote_path"
gzip -c "$file" | ssh "$remote" "gunzip -c > ${remote_path}/$(basename "$file")"
local local_md5 remote_md5
local_md5=$(md5sum "$file" | awk '{print $1}')
remote_md5=$(ssh "$remote" "md5sum ${remote_path}/$(basename "$file")" | awk '{print $1}')
if [[ "$local_md5" == "$remote_md5" ]]; then
echo "[+] 传输验证通过"
else
echo "[-] 传输验证失败"
return 1
fi
}
rsync_transfer() {
local source="$1" remote="$2" dest="$3"
rsync -avz --progress --partial \
-e "ssh -o StrictHostKeyChecking=no" \
"$source" "${remote}:${dest}"
echo "[+] rsync 同步完成"
}
rsync_resume() {
local source="$1" remote="$2" dest="$3"
rsync -avz --progress --partial --append-verify \
-e "ssh" \
"$source" "${remote}:${dest}"
echo "[+] 断点续传完成"
}4. 压缩 + 分卷传输
split_transfer() {
local file="$1" remote="$2" remote_path="$3"
local chunk_size="${4:-10M}"
echo "[*] 分卷传输: $file (每块 $chunk_size)"
# 分卷压缩
local split_prefix="/tmp/split_$$"
split -b "$chunk_size" "$file" "${split_prefix}_"
# 逐块传输
for part in "${split_prefix}"_*; do
echo " 传输: $(basename "$part")"
scp "$part" "$remote:${remote_path}/"
done
# 远程重组
ssh "$remote" "cat ${remote_path}/split_* > ${remote_path}/$(basename "$file")"
# 清理
rm -f "${split_prefix}"_*
echo "[+] 分卷传输完成"
}
split_receive() {
local remote="$1" remote_path="$2" local_file="$3"
ssh "$remote" "cat ${remote_path}/*" > "$local_file"
echo "[+] 接收完成: $local_file"
}5. 综合传输脚本
secure_transfer() {
local file="$1" remote="$2" remote_path="$3" password="$4"
local method="${5:-openssl}"
echo "[*] 安全传输: $file -> $remote:$remote_path (方法: $method)"
case "$method" in
openssl)
openssl_transfer "$file" "$remote" "$remote_path" "$password"
;;
scp)
scp_transfer "$file" "$remote" "$remote_path"
;;
rsync)
rsync_transfer "$file" "$remote" "$remote_path"
;;
split)
split_transfer "$file" "$remote" "$remote_path" "${6:-10M}"
;;
*)
echo "[-] 未知方法: $method"
return 1
;;
esac
}总结
本文介绍了使用 bash 工具链实现安全文件传输的完整方案:tar+openssl 打包加密、GPG 加密、SSH/SCP 安全传输、rsync 增量同步、分卷传输和断点续传。这些技术可以组合使用,确保数据在传输过程中的完整性和机密性。