Verifica descargas con cURL y b2sum
Descarga en un archivo temporal, compara su suma de verificación BLAKE2b con el valor de un editor
confiable y crea el destino solo cuando los bytes coincidan. El siguiente script de Bash combina
cURL y b2sum sin reemplazar un archivo existente; después se demuestra el
flujo de trabajo con una suma de verificación de una versión real.
Obtén la suma de verificación esperada del editor
Ejecutar b2sum sobre una descarga te indica su suma de verificación actual.
No te indica cuál debería ser. Obtén el valor esperado para la versión, la arquitectura y el nombre
de archivo exactos de un editor en el que confíes, por ejemplo, desde su página oficial de versiones
por HTTPS o un manifiesto de sumas de verificación cuya firma se haya verificado. Una suma de
verificación copiada del mismo sitio espejo no confiable que la descarga no aporta una referencia
fiable.
GNU b2sum usa BLAKE2b-512 de forma
predeterminada: 64 octetos de resumen escritos como 128 caracteres hexadecimales. Este script requiere
ese formato. BLAKE2s, un resumen BLAKE2b más corto y SHA-256 no son intercambiables con él. Si el
editor solo proporciona SHA-256, usa un flujo de verificación SHA-256 en lugar de inventar una
referencia BLAKE2b calculando tú mismo el hash del archivo descargado.
Comprueba los requisitos previos de Linux
Usa una máquina Linux que ya tenga instalados GNU Bash, cURL con soporte para HTTPS y GNU Coreutils.
Coreutils proporciona b2sum, mktemp,
ln y rm. Este ejemplo se probó con Bash 5.3.15,
cURL 8.22.0 y Coreutils 9.11; no es una guía para macOS ni PowerShell. Comprueba tus herramientas:
bash --version && curl --version && b2sum --version
Ejecuta el script en un directorio que controles, en un sistema de archivos que admita enlaces duros.
El destino es un nombre de archivo en ese directorio, no una ruta a otro directorio. Se permiten
espacios y guiones iniciales; se rechazan las barras, los saltos de línea,
. y ... El archivo se guarda con permisos de
lectura y escritura solo para el propietario, y cualquier archivo, directorio o enlace simbólico
existente se deja intacto.
Guarda el script de verificación completo
Guarda este script en un archivo nuevo llamado verify-download.sh. Ejecútalo con
bash; no lo pegues en tu shell interactivo, porque sus salidas por error
están pensadas para terminar el programa guardado.
#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
umask 077
if (( $# != 3 )); then
printf 'Usage: bash verify-download.sh HTTPS_URL BLAKE2B_512_HEX FILENAME\n' >&2
exit 2
fi
url=$1
expected=${2,,}
filename=$3
if [[ ! $expected =~ ^[0-9a-f]{128}$ ]]; then
printf 'Expected checksum must contain exactly 128 hexadecimal characters.\n' >&2
exit 2
fi
if [[ $url != https://* ]]; then
printf 'The download URL must use HTTPS.\n' >&2
exit 2
fi
if [[ -z $filename || $filename == */* || $filename == . || $filename == .. ||
$filename == *$'\n'* || $filename == *$'\r'* ]]; then
printf 'Use a filename without slashes or line breaks.\n' >&2
exit 2
fi
destination="./$filename"
if [[ -e $destination || -L $destination ]]; then
printf 'Destination already exists: %s\n' "$destination" >&2
exit 1
fi
temporary=$(mktemp -d ./.b2-download.XXXXXXXX)
trap 'rm -rf -- "$temporary"' EXIT
if ! curl -q -fsSL --globoff --proto '=https' --proto-redir '=https' \
--max-redirs 5 --connect-timeout 10 --max-time 300 \
--output "$temporary/payload" --url "$url"; then
printf 'Download failed; no file saved.\n' >&2
exit 1
fi
if ! printf '%s %s\n' "$expected" "$temporary/payload" |
b2sum --check --strict --status -; then
printf 'Checksum mismatch or unreadable download; no file saved.\n' >&2
exit 1
fi
if ! ln -T -- "$temporary/payload" "$destination"; then
printf 'Destination exists or cannot be created; no file saved.\n' >&2
exit 1
fi
printf 'Verified and saved: %s\n' "$destination"
La entrada de la suma de verificación usa el formato de GNU: el resumen, dos espacios y el nombre
del archivo. El script construye ese registro para su propio contenido temporal en lugar de dejar
que un manifiesto descargado elija rutas locales. --strict rechaza los
registros de sumas de verificación mal formados, mientras que la comprobación de argumentos exige
que el resumen tenga una longitud de 512 bits antes de cualquier transferencia.
El paso final usa un enlace duro, no
mv: GNU ln -T sin
--force falla si el destino existe, incluso si aparece después de la
comprobación inicial. Mantener el archivo temporal en el directorio de destino evita un enlace
entre sistemas de archivos. El manejador de salida elimina el directorio temporal privado tanto al
completarse normalmente como al fallar. Una terminación abrupta o un corte de energía pueden dejarlo
sin eliminar; esto no es un sistema de recuperación ante fallos.
Descarga una versión con una suma de verificación BLAKE2b publicada
La página de descargas de Arch Linux incluye un enlace a su manifiesto BLAKE2b. Para obtener un ejemplo reproducible, usa el archivo tar de arranque del 1 de septiembre de 2026, no una URL «latest» que cambie con el tiempo. Se trata de la descarga de un archivo contenedor de aproximadamente 121 MiB, no de una instrucción para instalar, extraer ni ejecutar esa versión.
Lee el manifiesto del editor correspondiente a esa versión a través de HTTPS:
curl -q -fsSL --proto '=https' --proto-redir '=https' --max-time 30 \
--url 'https://archive.archlinux.org/iso/2026.09.01/b2sums.txt'
Busca la línea que termina en archlinux-bootstrap-2026.09.01-x86_64.tar.zst. Copia su primer campo, no la suma de
verificación de la ISO ni una que hayas generado localmente. La siguiente invocación usa ese valor
publicado de 128 caracteres y guarda el archivo tar coincidente:
(
url='https://archive.archlinux.org/iso/2026.09.01/archlinux-bootstrap-2026.09.01-x86_64.tar.zst'
expected='3893c310ec7d52fd5dee7eec51bc9d611200a5636985c8b627871d1ee85d83821284bcb9a6843afa011a6607ee9ce3202f7e7f5f168f29a07541c0836eeaefd0'
bash verify-download.sh "$url" "$expected" archlinux-bootstrap-2026.09.01-x86_64.tar.zst
)
Si se completa correctamente, el programa guardado imprime:
Verified and saved: ./archlinux-bootstrap-2026.09.01-x86_64.tar.zst
Solo entonces se crea el destino. Un archivo vacío también es válido si coincide su suma de verificación esperada; el script verifica bytes, no si estos forman un archivo contenedor útil.
Interpreta los fallos antes de usar el archivo
- Suma de verificación no coincidente: no se crea ningún destino y se elimina la descarga temporal. Vuelve a comprobar la versión, la arquitectura y el valor esperado de confianza. No «corrijas» la discrepancia usando la suma de verificación de la propia descarga como valor esperado.
- Error de HTTP, TLS o transferencia incompleta: cURL falla, el script devuelve un valor distinto de cero y se elimina cualquier contenido parcial. La transferencia tiene un límite de cinco minutos; ajústalo de forma deliberada para descargas más grandes o conexiones más lentas.
- Destino existente: el script devuelve un valor distinto de cero y conserva los bytes del destino. Elige otro nombre de archivo en lugar de eliminar una descarga anterior sin comprobarla.
- Fallo de publicación: una operación de enlace duro no admitida o un destino creado durante la transferencia impide que el proceso se complete correctamente. La verificación por sí sola no significa que el archivo se haya guardado.
Las opciones de cURL hacen visibles los fallos de transferencia:
-f trata la mayoría de las respuestas de error HTTP como fallos,
-sS oculta el indicador de progreso, pero conserva los diagnósticos, y
-L sigue las redirecciones. Tanto la URL inicial como las redirecciones
se restringen a HTTPS, con un máximo de cinco redirecciones. -q va primero
para que una configuración local de curl no pueda cambiar silenciosamente las opciones de este
comando. Las redirecciones restringidas a HTTPS aún pueden cambiar de host; la suma de verificación
de confianza sigue siendo la referencia a nivel de bytes.
Comprende qué demuestra una suma de verificación coincidente
Una coincidencia establece la concordancia con el resumen esperado, no que el archivo sea inofensivo ni que lo haya publicado una persona determinada. En este ejemplo, la base de confianza es el sitio HTTPS del editor, Arch Linux. Si un atacante controla tanto el artefacto como esa fuente de la suma de verificación, puede reemplazar ambos. Para autenticar al editor más allá de esa base de confianza, sigue sus instrucciones de verificación de firmas y establece por separado la identidad de la clave de firma.
El script también supone que otros procesos no pueden modificar de forma maliciosa tu directorio de trabajo ni el archivo guardado. Es una comprobación local de la descarga, no un entorno aislado ni una garantía de que los bytes permanezcan sin cambios después de la verificación. En un flujo de trabajo de catalogación de medios, conserva la suma de verificación esperada junto con su fuente y la información de la versión, para que una comparación posterior tenga una referencia que puedas explicar.
