Deutsch

Entwicklertools · SHA-Hash-Rechner

Inhaltsadressierung: Wie Git, Docker und npm SHA-Digests als Namen verwenden

· Hintergrund

sha-256 Docker Kryptographie Entwickler-Workflow

Git-Commits, Docker-Layer und Paket-Hashes, die von ihren SHA-256-Digests adressiert werden
Original-ToolAcre-Vektorillustration

Git-Commits, Container-Image-Digests und Lockfile-Integritätszeichenfolgen basieren alle auf derselben Idee: die Benennung von Daten anhand ihres Hashs. In diesem Beitrag wird die Adressierung von Inhalten erläutert und erläutert, welche Vorteile jedes Ökosystem daraus hat.

Der sha256: in Ihrem Docker-Pull – was dieser String ist und warum er sich für dasselbe Bild nie ändert

Versionskontrollsysteme, Containerlaufzeiten und Paketmanager verwenden alle die gleiche Benennungsidee: Eine Datei oder eine Sammlung von Bytes wird nach ihrem SHA-Digest benannt. In Git wird der 40-Zeichen-SHA-1-Bezeichner (oder der 64-Zeichen SHA-256 in modernen Repositorys) aus dem Inhalt des Commits berechnet – dem Baum, dem Autor, dem Zeitstempel und der Nachricht. Ändern Sie ein einzelnes Byte und der SHA ändert sich. In Docker ist jeder Layer-Digest ein SHA-256-Hash des Inhalts der Ebene, und der Image-Digest wird aus dem Manifest berechnet. In npm und anderen Paketmanagern speichern Integritätsfelder SHA-512 Digests von Tarballs, um Downloads zu überprüfen. Inhaltsadressierung bedeutet, dass der Name nur von den Bytes abhängt, nicht von einer zentralen Datenbank oder einem Zeitstempel.

Der Vorteil ist die Unveränderlichkeit innerhalb jedes Systems. Ein Git-Commit SHA-256:abc... verweist immer auf denselben Baum und dieselbe Nachricht, da der Hash die Identität bestimmt. Wenn jemand behauptet, einen anderen Commit mit demselben SHA zu haben, behauptet er, dass dieselben Bytes zwei verschiedene Hashes erzeugen, was die Kryptographie unterbricht. Die Deduplizierung erfolgt automatisch: Zwei Dateien mit identischen Bytes erzeugen denselben Digest, sodass Speichersysteme die Bytes einmal speichern und zweimal referenzieren können. Die Integritätsprüfung ist so einfach wie die Neuberechnung und der Vergleich des Digests: Wenn die Bytes während der Übertragung oder im Ruhezustand geändert wurden, stimmt der Digest nicht mehr überein.

Benennen von Daten nach ihrem Hash – die Idee der Inhaltsadressierung und warum sie Deduplizierung und Integrität frei macht

Git speichert Objekte – Commits, Bäume, Blobs und Tags – verschlüsselt durch ihren SHA-Digest. Der Befehl `git cat-file` nimmt eine Objekt-ID und ruft die Bytes ab. Der Objektspeicher ist inhaltsadressiert: Sie fordern nach Digest an, nicht nach Standort oder Name. Wenn Sie ein Repository klonen, überprüft Git jedes Objekt, indem es seinen Digest neu berechnet und mit dem in der Übertragung gepackten Digest vergleicht. Der Übergang von SHA-1 zu SHA-256 erfolgt schrittweise; Repositorys können aus Kompatibilitätsgründen beide unterstützen. Das On-Disk-Format speichert Objekttyp, Größe und komprimierte Bytes. Der Digest wird über die kanonische unkomprimierte Form berechnet.

Moderne Git-Repositorys können SHA-256 verwenden, und der Übergang ist im Gange, da SHA-1-Kollisionen jetzt praktisch sind (demonstriert in 2017 und verfeinert in 2020). Ein Commit in einem Repository, das SHA-256 verwendet, hat einen Hex-Bezeichner mit 64-Zeichen anstelle von 40. Der Befehl `git hash-object` berechnet den SHA eines Blobs (Dateiinhalte), ohne ihn zu speichern. `git commit-tree` berechnet den SHA einer Baumstruktur und einer Nachricht. Beide Operationen sind deterministisch: Dieselben Bytes erzeugen immer denselben Digest. Auf diese Weise können GitHub und andere Forges Commit-SHAs konsistent anzeigen – sie berechnen denselben Digest, den der Klon des Autors berechnet hat.

Git verwendet inhaltsadressierte Objekte und dieses Tool kann Textauszüge reproduzieren; Migrationsdetails erfordern Git-spezifische Quellen

Docker-Images werden in Schichten erstellt, wobei jede Schicht ein Dateisystemdelta ist (Änderungen gegenüber der vorherigen Schicht). Die OCI-Image-Spezifikation definiert, wie der Digest einer Ebene und der Digest des Bildmanifests berechnet werden. Der Layer-Digest ist der SHA-256 der komprimierten TAR-Datei, die die Layer-Dateien enthält. Das Manifest ist ein JSON-Dokument, das Ebenen, ihre Digests und Metadaten auflistet. Der Image-Digest ist der SHA-256 des Manifests JSON selbst. Wenn Sie ein Image mit einem Tag wie `latest` abrufen, sucht die Registrierung nach dem Tag und gibt den Manifest-Digest zurück. Anschließend können Sie den Digest direkt abrufen und so sicherstellen, dass Sie jedes Mal genau die gleichen Bytes – alle Ebenen und Metadaten – erhalten.

Der Befehl `docker inspect` für ein lokales Image zeigt seinen Digest an. Das Ausführen desselben Images mit demselben Tag auf zwei Computern erzeugt denselben Digest, wenn die Registrierung immer noch dieses Tag enthält, das auf dasselbe Manifest verweist. Durch die Adressierung von Inhalten sind Image-Lieferketten überprüfbar: Eine CI/CD-Pipeline kann überprüfen, ob das bereitgestellte Image mit dem Digest im Build-Protokoll übereinstimmt, und ein Sicherheitsscanner kann alle Images, von denen bekannt ist, dass sie eine bestimmte Schwachstelle aufweisen, anhand ihres Digests und nicht anhand von Tags melden, die verschoben werden können.

Container – OCI-Manifeste und Layer-Digests und warum ein Tag verschoben werden kann, ein Digest jedoch nicht

Paketmanager verwenden Digests, um Downloads auf Manipulation oder Beschädigung zu überprüfen. In npm enthält die Datei `package-lock.json` ein Feld `integrity` für jede Abhängigkeit, das einen Hash (normalerweise SHA-512) und die Codierung (normalerweise Base64) enthält. Wenn npm einen Tarball herunterlädt, berechnet es den Hash neu und vergleicht ihn. Wenn die Hashes nicht übereinstimmen, schlägt die Installation fehl. Go verwendet eine `go.sum`-Datei mit ähnlicher Struktur: Modulpfad, Version und SHA-256 der Modulquelle. Cargo verwendet Prüfsummen in `Cargo.lock`. Das Prinzip ist identisch: Der Digest wird einmal berechnet, wenn die Abhängigkeit zum ersten Mal aufgelöst wird, und bei jeder nachfolgenden Installation überprüft.

Für die Integritätsprüfung ist es nicht erforderlich, das Paket zu einer Signierungsstelle hochzuladen oder Signaturen separat zu speichern. Der Digest ist die Integritätsprüfung. Für maximale Sicherheit verwenden Projekte `go.sum`, das vom Transparenzsystem des Go-Projekts signiert ist, oder npm-Integrität in Kombination mit anderen Überprüfungen. Der Basisfall ist jedoch einfach: Der Herausgeber berechnet den Digest einmal, zeichnet ihn in der Sperrdatei auf und Tools auf der Verbraucherseite überprüfen, ob die heruntergeladenen Bytes übereinstimmen.

Paketintegritätskodierungen variieren; Hier werden nur die von diesem Rechner unterstützten SHA-Ausgaben geltend gemacht

Dieselben Bytes durch denselben Algorithmus erzeugen immer denselben Digest, unabhängig davon, woher die Bytes kommen. Der lokale Build eines Commits durch einen Entwickler erzeugt dasselbe SHA-256 wie ein CI/CD-System, das dieselbe Revision aus demselben Repository auscheckt. Diese Reproduzierbarkeit ist der Grund, warum die Inhaltsadressierung funktioniert: Sie können ein Artefakt überprüfen, ohne dem Bereitstellungsmechanismus zu vertrauen. Der Digest wird zu einer kryptografischen Verpflichtung: Eine Änderung auch nur eines Bytes macht ihn ungültig.

Die separate Verteilung des Digests (vor der Verteilung des Artefakts) schützt vor Änderungen während der Übertragung. Auf einer vor der Veröffentlichung veröffentlichten Webseite kann „expect SHA-256:abc...“ angezeigt werden, und dann können Benutzer Downloads anhand dieser Seite überprüfen. Ein in einem öffentlichen Repository veröffentlichtes Git-Commit ist eine Verpflichtung gegenüber den Bytes; Der Digest beweist es.

Bearbeitetes Beispiel – Verfolgen eines Blobs von den zu verdauenden Bytes bis zum Namen, den ein Tool dafür verwendet

Verschiedene Systeme kodieren ihre Digests unterschiedlich. Git verwendet standardmäßig hexadezimale Kleinbuchstaben (40 oder 64 Hexadezimalzeichen). Docker verwendet das Format `sha256:` gefolgt von Hex. npm und Go verwenden base64 in Integritätsfeldern. Die Bytes sind gleich; lediglich die Darstellung unterscheidet sich. Ein SHA-256-Digest über „abc“ besteht immer aus den gleichen 256 Bits, aber Sie sehen ihn möglicherweise als 64-Zeichen-Hex-String, als 44-Zeichen-Base64-String oder als Label wie `sha256:`, gefolgt von einem von beiden. Die Konvertierung zwischen Kodierungen ist verlustfrei; Der Digest hat in jeder Darstellung den gleichen Wert.

Beim Vergleich von Digests verschiedener Tools ist es wichtig, die Kodierung zu verstehen. Wenn Git einen Hex-Digest ausgibt und ein Tool base64 anzeigt, müssen Sie eine Darstellung in die andere konvertieren, um zu überprüfen, ob sie übereinstimmen. Der SHA-Hash-Rechner von ToolAcre zeigt für jeden Digest sowohl Hex als auch Base64 an und erleichtert so die Konvertierung oder den Vergleich mit anderen Systemen.

Was hier nicht behandelt wird – die spezifischen Kodierungen, die jedes Tool verwendet (Hex vs. Base64), werden in einem separaten Beitrag behandelt

Die Adressierung von Inhalten ist nicht spezifisch für die Kryptografie, obwohl kryptografische Hashes sie sicher machen. Eine CRC32-Prüfsumme dient auch der Inhaltsadressierung von Daten, aber CRC32-Kollisionen kommen häufig vor und Kollisionen können erzeugt werden; Dieses Repository markiert SHA-256 nicht als defekt, während CRC32 nicht als gegnerisches Integritätsprimitiv angeboten wird. Die Wahl des Hash-Algorithmus ist aus Sicherheitsgründen wichtig: SHA-256 ist der moderne Standard für Systeme, die einen Integritätsschutz vor Angreifern benötigen. SHA-1 ist nur Legacy (Git und andere migrieren weg). Die Wahl des richtigen Algorithmus ist eine andere Entscheidung als die Wahl der Inhaltsadressierung als Benennungsschema.

Inhaltsadressierung in Kombination mit kryptografischen Hashes ist die Grundlage für die Integrität der Lieferkette in moderner Software. Bei jedem Paket, das Sie installieren, bei jedem Container, den Sie ausführen, und bei jedem Commit, das Sie auschecken, kann überprüft werden, ob es sich um die vom ursprünglichen Herausgeber vorgesehenen Bytes handelt, ohne dass Sie sich auf eine sichere Übertragung verlassen müssen (obwohl eine sichere Übertragung immer noch eine gute Praxis ist).

Fazit: Der Hash ist die Identität – mit dem ToolAcre SHA-Hash-Rechner können Sie dieselben Digests berechnen, auf die sich diese Systeme verlassen

Die Inhaltsadressierung ist unabhängig von der Kodierung, dem Speicherort oder dem Übertragungsmechanismus. Dieselben Bytes erzeugen denselben Digest, unabhängig davon, ob sie lokal, in einem CDN, in einer Registrierung gespeichert oder über HTTP oder sicheres HTTPS übertragen werden. Beim Digest handelt es sich um eine kryptografische Verpflichtung gegenüber den Bytes. Für die Überprüfung sind nur die Bytes und der Algorithmus erforderlich, kein externer Dienst. Aus diesem Grund ermöglicht die Inhaltsadressierung eine Offline-Verifizierung: Sie können eine Datei über einen nicht vertrauenswürdigen Kanal herunterladen, den Digest überprüfen und feststellen, ob die Bytes authentisch sind.

Mit dem ToolAcre SHA-Hash-Rechner können Sie dieselben Digests berechnen, auf die diese Systeme angewiesen sind. Fügen Sie eine Zeichenfolge ein oder sehen Sie sich eine Datei an, führen Sie den Rechner aus und sehen Sie sich die Digests SHA-256, SHA-384 und SHA-512 an, die Docker, Git, npm und andere Tools intern verwenden. Vergleichen Sie Ihren berechneten Digest mit dem aus der Originalquelle, um sicherzustellen, dass die Bytes nicht geändert wurden. Der Rechner hasht UTF-8 Text, den Sie einfügen; Dateien oder Schlüsselmaterial werden nicht gehasht, daher ist die Grenze zwischen dem, was gehasht werden kann (Texteingabe) und dem, was nicht gehasht werden kann (Binärdateien, kryptografische Schlüssel in ihrer codierten Form), klar und dokumentiert.