Télécharger des fichiers avec cURL et vérifier les sommes SHA-256
Utilisez cURL pour télécharger un fichier et sha256sum pour comparer ses octets à une somme de contrôle
fiable. Le script Bash ci-dessous conserve le téléchargement dans un répertoire temporaire et ne lui
attribue son nom de fichier définitif qu’une fois la vérification réussie. Vous pouvez exécuter le
même script en local et dans GitHub Actions.
Choisir une somme de contrôle fiable
SHA-256 produit une empreinte de 256 bits, généralement écrite sous la forme de 64 caractères hexadécimaux. Une empreinte correspondante vérifie les octets téléchargés par rapport à la valeur attendue. Elle n’établit pas qui a fourni cette valeur : quiconque peut remplacer à la fois un téléchargement et sa somme de contrôle peut les faire concorder.
Obtenez la somme de contrôle attendue à partir des métadonnées de version de l’éditeur via HTTPS et conservez-la avec l’URL versionnée que vous comptez télécharger. Si vous devez authentifier la version indépendamment de son site d’hébergement, suivez la procédure de vérification de signature de l’éditeur en utilisant une clé de signature dont vous avez établi l’identité de manière indépendante. Le projet cURL fournit des signatures détachées pour ses archives de version ; l’exemple de somme de contrôle présenté ici ne vérifie pas ces signatures.
Automatiser la vérification avec Bash
Utilisez Linux avec Bash, une version de cURL prenant en charge HTTPS et GNU coreutils : sha256sum,
mktemp, ln et rm. La destination est le répertoire courant, qui doit être accessible en écriture
et situé sur un système de fichiers prenant en charge les liens physiques. Ce script utilise GNU
ln -T ; il ne s’agit pas d’un script /bin/sh portable ni d’un script macOS.
Les exemples ont été testés avec Bash 5.2.21, cURL 8.5.0 et coreutils 9.4 sous Ubuntu 24.04, ainsi
qu’avec Bash 5.3.15, cURL 8.22.0 et coreutils 9.11 sous Linux.
Enregistrez ce fichier sous verify-download.sh dans un répertoire que vous contrôlez. Exécutez-le avec Bash comme
indiqué ci-dessous ; ne le chargez pas dans votre shell avec la commande source. Les trois arguments
sont l’URL HTTPS, l’empreinte SHA-256 attendue et un nom de fichier local. Les noms de sortie peuvent
contenir des espaces, des traits d’union initiaux ou des caractères % littéraux, mais ne doivent
pas contenir de barre oblique ni de saut de ligne. Un fichier, un répertoire ou un lien symbolique
existant provoque une erreur et reste intact.
#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
if [[ $# -ne 3 ]]; then
printf 'Usage: bash verify-download.sh HTTPS_URL SHA256 OUTPUT_NAME\n' >&2
exit 2
fi
url=$1
expected=$2
output=$3
if [[ $url != https://* || ! $expected =~ ^[[:xdigit:]]{64}$ ]]; then
printf 'Provide an HTTPS URL and a 64-digit hexadecimal SHA-256 checksum.\n' >&2
exit 2
fi
case "$output" in
''|.|..|*/*|*$'\n'*|*$'\r'*)
printf 'Provide a filename without slashes or line breaks.\n' >&2
exit 2
;;
esac
if [[ -e "./$output" || -L "./$output" ]]; then
printf 'Destination already exists: %s\n' "$output" >&2
exit 1
fi
umask 077
temp_dir=$(mktemp -d ./.verify-download.XXXXXX)
trap 'rm -rf -- "$temp_dir"' EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
curl -q -fsSL --globoff --proto '=https' --proto-redir '=https' \
--connect-timeout 10 --max-time 120 --retry 3 \
--output "$temp_dir/payload" --url "$url"
if ! printf '%s %s\n' "$expected" "$temp_dir/payload" | sha256sum --check --status -; then
printf 'SHA-256 mismatch or unreadable download.\n' >&2
exit 1
fi
ln -T -- "$temp_dir/payload" "./$output"
printf 'Verified: %s\n' "$output"
Les options de cURL font échouer les erreurs HTTP telles qu’une erreur 404 (-f),
masquent l’indicateur de progression tout en conservant les messages d’erreur (-sS) et suivent les
redirections (-L). La requête initiale comme les redirections sont limitées à HTTPS.
--globoff traite l’URL de manière littérale ; -q, placé en premier, empêche un .curlrc local de
modifier la requête. Les échecs transitoires donnent lieu à trois nouvelles tentatives au maximum,
avec une limite de 120 secondes par tentative de transfert.
Le script construit un seul enregistrement de somme de contrôle : l’empreinte, deux espaces et le
chemin privé de la charge utile.
GNU sha256sum --check
lit cet enregistrement depuis l’entrée standard. --status fait en sorte que le code de sortie détermine
si la vérification a réussi. Aucun fichier de sommes de contrôle distant ne peut choisir quels noms
de fichiers locaux sont vérifiés.
Après une correspondance, GNU ln
ajoute le nom définitif au fichier déjà vérifié. -T traite la destination comme un nom exact,
y compris lorsqu’un répertoire s’y trouve, et l’absence de -f empêche tout remplacement. Placer
le répertoire temporaire à côté de la destination garantit que les deux noms se trouvent sur le même
système de fichiers. Le gestionnaire de sortie (trap) supprime le nom temporaire et le répertoire ;
le fichier vérifié reste sous son nom définitif.
En cas d’échec du téléchargement ou de la somme de contrôle, le script renvoie un code non nul et
supprime les données temporaires sans créer le fichier final. Chaque nouvelle exécution lance un
nouveau téléchargement ; elle ne reprend pas les octets partiels. Les traps gèrent aussi les
interruptions normales, mais une coupure de courant ou SIGKILL peut laisser un répertoire .verify-download.*
à nettoyer manuellement. Il s’agit d’un téléchargement dans un répertoire qui vous appartient, et non
d’une protection contre un autre processus capable de modifier vos fichiers.
Vérifier une version de cURL
La version 8.22.0 de cURL inclut
curl-8.22.0.tar.gz. Ses
métadonnées de version indiquent comme digest de cette ressource
précise la valeur
sha256:d54dd598bf05927a726deb38df31c6a255ba83ff1de57c5d1464dac3ed8f44a1.
Utilisez les 64 caractères qui suivent sha256: comme valeur attendue. Les ressources .tar.xz et
.zip ont des octets et des sommes de contrôle différents.
Il s’agit de métadonnées JSON, et non d’un fichier d’entrée pour sha256sum --check. Ne devinez pas l’URL d’une
somme de contrôle en ajoutant .sha256 à une URL de téléchargement : curl-8.5.0.tar.gz.sha256 n’héberge aucun fichier
à cette adresse. Ici, nous épinglons l’empreinte publiée pour la ressource de la version et
téléchargeons l’archive depuis
curl.se :
bash verify-download.sh \
'https://curl.se/download/curl-8.22.0.tar.gz' \
'd54dd598bf05927a726deb38df31c6a255ba83ff1de57c5d1464dac3ed8f44a1' \
'curl-8.22.0.tar.gz'
En cas de réussite, la commande se termine avec le code de sortie zéro et affiche :
Verified: curl-8.22.0.tar.gz
L’archive se trouve maintenant dans votre répertoire courant. Cette commande télécharge le code source ; elle n’installe ni ne met à niveau cURL. Pour répéter l’exemple, utilisez un autre nom de sortie ou supprimez d’abord délibérément le téléchargement précédent. Pour vérifier une autre version, sélectionnez sa ressource exacte et mettez à jour à la fois l’URL et l’empreinte.
Intégration à GitHub Actions
Placez verify-download.sh à la racine de votre dépôt et enregistrez ce flux de travail sous
.github/workflows/verify-download.yml. Il utilise la même URL et la même empreinte épinglées. La dernière étape
liste l’archive vérifiée avec les commandes tar et gzip d’Ubuntu ; remplacez-la par votre
étape de compilation une fois la vérification fonctionnelle.
name: Verify download
on: [push, pull_request]
permissions:
contents: read
jobs:
verify:
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
- name: Download and verify
shell: bash
run: |
bash verify-download.sh \
'https://curl.se/download/curl-8.22.0.tar.gz' \
'd54dd598bf05927a726deb38df31c6a255ba83ff1de57c5d1464dac3ed8f44a1' \
'curl-8.22.0.tar.gz'
- name: Read verified archive
shell: bash
run: tar -tzf curl-8.22.0.tar.gz > /dev/null
Par défaut, GitHub Actions arrête les étapes suivantes après un échec.
Conservez ce comportement : ajouter continue-on-error ou un || true forçant la réussite permettrait à une
étape ultérieure de s’exécuter malgré l’échec de la vérification. Examinez les changements de somme
de contrôle en même temps que les mises à jour de dépendances ; calculer une empreinte « attendue »
à partir du fichier fraîchement téléchargé ne ferait que le comparer à lui-même.
Dépannage
- Erreur HTTP, notamment
curl: (22): vérifiez l’URL exacte de la ressource. Une page d’erreur ne doit pas devenir votre archive de version. Une redirection vers HTTP est également rejetée, même si la destination est accessible. - Transfert partiel, par exemple
curl: (18): le serveur a fermé la réponse avant que la longueur annoncée ne soit atteinte. Réessayez après avoir vérifié la connexion. Si le serveur présente un fichier plus court comme une réponse réussie, la comparaison des sommes de contrôle rejette tout de même les octets modifiés. - Empreinte SHA-256 non concordante : vérifiez la version et l’extension de l’archive par rapport aux métadonnées de l’éditeur. Ne remplacez pas la somme de contrôle attendue par la valeur du téléchargement suspect.
- La destination existe déjà : le fichier précédent est conservé. Choisissez un autre nom local, ou examinez et supprimez vous-même le téléchargement précédent.
- Erreur de lien physique ou d’écriture : utilisez un système de fichiers local accessible en écriture qui prend en charge les liens physiques. Un échec de l’étape de publication renvoie un code non nul même si la somme de contrôle correspondait.
