Der ETag-Header ist MD5, jedoch nicht für mehrteilige Dateien. Hier ist mehr Infos, wie Sie es verwenden können: stackoverflow.com/questions/6591047/…
r03
2
Gibt es keine Möglichkeit, einen MD5 für ein S3-Objekt zu berechnen, ohne das gesamte Objekt abzurufen und lokal zu berechnen? Derzeit befasst sich keine der Antworten mit dieser sehr einfachen Frage und konzentriert sich stattdessen ausschließlich auf das ETag. Die meisten Antworten, die die Verwendung des ETag vorschlagen, geben sogar zu, dass es kein geeigneter Ersatz für ein berechnetes MD5 ist.
bsplosion
Antworten:
31
Die Dokumentation von AWS ETaglautet:
Das Entity-Tag ist ein Hash des Objekts. Das ETag spiegelt nur Änderungen am Inhalt eines Objekts wider, nicht dessen Metadaten. Das ETag kann ein MD5-Digest der Objektdaten sein oder nicht. Ob dies der Fall ist oder nicht, hängt davon ab, wie das Objekt erstellt und wie unten beschrieben verschlüsselt wurde:
Objekte, die vom PUT-Objekt-, POST-Objekt- oder Kopiervorgang oder über die AWS Management Console erstellt und mit SSE-S3 oder Klartext verschlüsselt wurden, verfügen über ETags, die einen MD5-Digest ihrer Objektdaten darstellen.
Objekte, die durch den Vorgang PUT-Objekt, POST-Objekt oder Kopieren oder über die AWS Management Console erstellt und von SSE-C oder SSE-KMS verschlüsselt wurden, verfügen über ETags, die keine MD5-Zusammenfassung ihrer Objektdaten darstellen.
Wenn ein Objekt entweder durch das Hochladen mehrerer Teile oder durch das Kopieren von Teilen erstellt wird, ist das ETag unabhängig von der Verschlüsselungsmethode kein MD5-Digest.
ETag scheint kein MD5 für mehrteilige Uploads zu sein (gemäß dem Kommentar von Gael Fraiteur). In diesen Fällen enthält es ein Suffix von Minus und eine Zahl. Selbst das Bit vor dem Minus scheint jedoch nicht das MD5 zu sein, obwohl es die gleiche Länge wie ein MD5 hat. Möglicherweise ist das Suffix die Anzahl der hochgeladenen Teile?
Dieses Suffix scheint nur zu erscheinen, wenn die Datei groß ist (größer als 5 GB). Wenn ich mir die wenigen Dateien ansehe, die groß sind, scheint das Suffix die Anzahl der hochgeladenen Teile darzustellen. Der erste Teil scheint jedoch nicht den gleichen md5-Hash wie die Originaldatei zu haben. Bei der Berechnung dieses Hashs muss amazon einige zusätzliche Daten für jedes Teil einklappen. Ich möchte den Algorithmus kennen, damit ich einige meiner Dateien überprüfen kann.
@ broc.seib Ich sehe ein Suffix für Dateien, die viel kleiner sind, z. B. 18,3 MB. Ich frage mich, ob es davon abhängt, was zum Hochladen der Datei verwendet wird. Ich benutzeaws s3 cp ...
Bei der Verwendung der etag_checksumFunktion ist ein Problem mit Dateien aufgetreten, die kleiner als diese sind chunkt_size. Ein einfacher Test der Dateigröße ( os.path.getsize(filename) < chunk_size) hat dies behoben, falls auch jemand anderes dieses Problem hat. In diesem Fall lautet der Hashhashlib.md5(f.read())
KingBugAndTheCodeWizard
4
Für alle, die Zeit damit verbringen, sich umzuschauen, um herauszufinden, warum der md5 nicht mit ETag in S3 identisch ist.
ETag berechnet gegen das Einspannen von Daten und konzentriert alle md5hash, um md5-Hash erneut zu erstellen und die Anzahl der Chunks am Ende beizubehalten.
Hier ist die C # -Version zum Generieren von Hash
string etag = HashOf("file.txt",8);
Quellcode
private string HashOf(string filename,int chunkSizeInMb)
{
string returnMD5 = string.Empty;
int chunkSize = chunkSizeInMb * 1024 * 1024;
using (var crypto = new MD5CryptoServiceProvider())
{
int hashLength = crypto.HashSize/8;
using (var stream = File.OpenRead(filename))
{
if (stream.Length > chunkSize)
{
int chunkCount = (int)Math.Ceiling((double)stream.Length/(double)chunkSize);
byte[] hash = new byte[chunkCount*hashLength];
Stream hashStream = new MemoryStream(hash);
long nByteLeftToRead = stream.Length;
while (nByteLeftToRead > 0)
{
int nByteCurrentRead = (int)Math.Min(nByteLeftToRead, chunkSize);
byte[] buffer = new byte[nByteCurrentRead];
nByteLeftToRead -= stream.Read(buffer, 0, nByteCurrentRead);
byte[] tmpHash = crypto.ComputeHash(buffer);
hashStream.Write(tmpHash, 0, hashLength);
}
returnMD5 = BitConverter.ToString(crypto.ComputeHash(hash)).Replace("-", string.Empty).ToLower()+"-"+ chunkCount;
}
else {
returnMD5 = BitConverter.ToString(crypto.ComputeHash(stream)).Replace("-", string.Empty).ToLower();
}
stream.Close();
}
}
return returnMD5;
}
Dieser Code funktioniert bei mir für kleine Dateien. Große Dateien geben mir einen anderen Hash
Tono Nam
Wie groß ist die Datei?
Pitipong Guntawong
Wie erhalte ich die Blockgröße des mehrteiligen s3-Objektschlüssels?
Daniel
Abhängig von der Upload-Software. Sie können die
Blockgröße festlegen,
4
Dies ist eine sehr alte Frage, aber es fiel mir schwer, die folgenden Informationen zu finden, und dies ist einer der ersten Orte, die ich finden konnte. Deshalb wollte ich sie detailliert beschreiben, falls jemand sie benötigt.
ETag ist ein MD5. Für die hochgeladenen Multipart-Dateien wird der MD5 jedoch aus der Verkettung der MD5s jedes hochgeladenen Teils berechnet. Sie müssen den MD5 also nicht auf dem Server berechnen. Holen Sie sich einfach den ETag und es ist alles.
Angenommen, Sie haben eine 14-MB-Datei hochgeladen und Ihre Teilegröße beträgt 5 MB. Berechnen Sie 3 MD5-Prüfsummen für jedes Teil, dh die Prüfsumme der ersten 5 MB, der zweiten 5 MB und der letzten 4 MB. Nehmen Sie dann die Prüfsumme ihrer Verkettung. Da MD5-Prüfsummen hexadezimale Darstellungen von Binärdaten sind, stellen Sie sicher, dass Sie das MD5 der decodierten binären Verkettung und nicht der ASCII- oder UTF-8-codierten Verkettung verwenden. Wenn dies erledigt ist, fügen Sie einen Bindestrich und die Anzahl der Teile hinzu, um das ETag zu erhalten.
Das einzige andere, was Sie brauchen, ist das ETag und die Upload-Teilegröße. Das ETag hat jedoch das Suffix -NumberOfParts. So können Sie die Größe durch das Suffix teilen und die Teilegröße erhalten. 5 MB ist die minimale Teilegröße und der Standardwert. Die Teilegröße muss eine Ganzzahl sein, damit Sie nicht 7,25 MB pro Teilegröße erhalten können. Es sollte also einfach sein, Informationen zur Teilegröße zu erhalten.
Dies ist praktisch, aber wie in mehreren anderen Antworten erwähnt, ist dies bei einigen Dateien nicht die tatsächliche MD5-Summe, sondern eine andere Art von Hash.
Ian Greenleaf Young
2
Ich habe den s3cmd-Quellcode überprüft und er speichert md5 beim Hochladen in Metadaten. Dieser Befehl druckt also nur md5 für Objekte, die mit s3cmd hochgeladen wurden, oder für Objekte, die in einem einzelnen Block hochgeladen wurden
ZAB
0
Ich habe jets3t und die Verwaltungskonsole mit der MD5sum der hochgeladenen Dateien verglichen, und ETag scheint MD5sum zu entsprechen. Sie können die Eigenschaften der Datei einfach in der AWS-Verwaltungskonsole anzeigen:
Am einfachsten ist es, die Prüfsumme selbst als Metadaten festzulegen, bevor Sie diese Dateien in Ihren Bucket hochladen:
ObjectMetadata md = new ObjectMetadata();
md.setContentMD5("foobar");
PutObjectRequest req = new PutObjectRequest(BUCKET, KEY, new File("/path/to/file")).withMetadata(md);
tm.upload(req).waitForUploadResult();
Jetzt können Sie auf diese Metadaten zugreifen, ohne die Datei herunterladen zu müssen:
Antworten:
Die Dokumentation von AWS
ETag
lautet:Referenz: http://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonResponseHeaders.html
quelle
ETag scheint kein MD5 für mehrteilige Uploads zu sein (gemäß dem Kommentar von Gael Fraiteur). In diesen Fällen enthält es ein Suffix von Minus und eine Zahl. Selbst das Bit vor dem Minus scheint jedoch nicht das MD5 zu sein, obwohl es die gleiche Länge wie ein MD5 hat. Möglicherweise ist das Suffix die Anzahl der hochgeladenen Teile?
quelle
aws s3 cp ...
Im Folgenden kann ich die Prüfsumme für lokale Dateien mit s3 etag vergleichen. Ich habe Python benutzt
def md5_checksum(filename): m = hashlib.md5() with open(filename, 'rb') as f: for data in iter(lambda: f.read(1024 * 1024), b''): m.update(data) return m.hexdigest() def etag_checksum(filename, chunk_size=8 * 1024 * 1024): md5s = [] with open(filename, 'rb') as f: for data in iter(lambda: f.read(chunk_size), b''): md5s.append(hashlib.md5(data).digest()) m = hashlib.md5(b"".join(md5s)) print('{}-{}'.format(m.hexdigest(), len(md5s))) return '{}-{}'.format(m.hexdigest(), len(md5s)) def etag_compare(filename, etag): et = etag[1:-1] # strip quotes print('et',et) if '-' in et and et == etag_checksum(filename): return True if '-' not in et and et == md5_checksum(filename): return True return False def main(): session = boto3.Session( aws_access_key_id=s3_accesskey, aws_secret_access_key=s3_secret ) s3 = session.client('s3') obj_dict = s3.get_object(Bucket=bucket_name, Key=your_key) etag = (obj_dict['ETag']) print('etag', etag) validation = etag_compare(filename,etag) print(validation) etag_checksum(filename, chunk_size=8 * 1024 * 1024) return validation
quelle
your_key
gleiche wie dasfilename
?etag_checksum
Funktion ist ein Problem mit Dateien aufgetreten, die kleiner als diese sindchunkt_size
. Ein einfacher Test der Dateigröße (os.path.getsize(filename) < chunk_size
) hat dies behoben, falls auch jemand anderes dieses Problem hat. In diesem Fall lautet der Hashhashlib.md5(f.read())
Für alle, die Zeit damit verbringen, sich umzuschauen, um herauszufinden, warum der md5 nicht mit ETag in S3 identisch ist.
ETag berechnet gegen das Einspannen von Daten und konzentriert alle md5hash, um md5-Hash erneut zu erstellen und die Anzahl der Chunks am Ende beizubehalten.
Hier ist die C # -Version zum Generieren von Hash
Quellcode
quelle
Dies ist eine sehr alte Frage, aber es fiel mir schwer, die folgenden Informationen zu finden, und dies ist einer der ersten Orte, die ich finden konnte. Deshalb wollte ich sie detailliert beschreiben, falls jemand sie benötigt.
ETag ist ein MD5. Für die hochgeladenen Multipart-Dateien wird der MD5 jedoch aus der Verkettung der MD5s jedes hochgeladenen Teils berechnet. Sie müssen den MD5 also nicht auf dem Server berechnen. Holen Sie sich einfach den ETag und es ist alles.
Wie @EmersonFarrugia in dieser Antwort sagte :
Das einzige andere, was Sie brauchen, ist das ETag und die Upload-Teilegröße. Das ETag hat jedoch das Suffix -NumberOfParts. So können Sie die Größe durch das Suffix teilen und die Teilegröße erhalten. 5 MB ist die minimale Teilegröße und der Standardwert. Die Teilegröße muss eine Ganzzahl sein, damit Sie nicht 7,25 MB pro Teilegröße erhalten können. Es sollte also einfach sein, Informationen zur Teilegröße zu erhalten.
Hier ist ein Skript, um dies in osx zu machen, mit einer Linux-Version in Kommentaren: https://gist.github.com/emersonf/7413337
Ich werde beide Skripte hier belassen, falls die obige Seite in Zukunft nicht mehr zugänglich ist:
Linux-Version:
OSX-Version:
quelle
Ich habe festgestellt, dass s3cmd eine Option --list-md5 hat, die mit dem Befehl ls verwendet werden kann, z
Hoffe das hilft.
quelle
Ich habe jets3t und die Verwaltungskonsole mit der MD5sum der hochgeladenen Dateien verglichen, und ETag scheint MD5sum zu entsprechen. Sie können die Eigenschaften der Datei einfach in der AWS-Verwaltungskonsole anzeigen:
https://console.aws.amazon.com/s3/home
quelle
Am einfachsten ist es, die Prüfsumme selbst als Metadaten festzulegen, bevor Sie diese Dateien in Ihren Bucket hochladen:
ObjectMetadata md = new ObjectMetadata(); md.setContentMD5("foobar"); PutObjectRequest req = new PutObjectRequest(BUCKET, KEY, new File("/path/to/file")).withMetadata(md); tm.upload(req).waitForUploadResult();
Jetzt können Sie auf diese Metadaten zugreifen, ohne die Datei herunterladen zu müssen:
Quelle: https://github.com/aws/aws-sdk-java/issues/1711
quelle
Das funktioniert bei mir. In PHP können Sie die Prüfsumme zwischen lokaler Datei und Amazon-Datei folgendermaßen vergleichen:
quelle
Hier ist der Code zum Abrufen des S3 ETag für ein Objekt in PowerShell, das aus c # konvertiert wurde.
quelle
Hier ist der Code, um MD5-Hash ab 2017 zu erhalten
Der kommentierte Code ist der Punkt, an dem die meisten Leute etwas falsch machen, wenn sie ihn in hexadezimal ändern
quelle