amazon-s3 - putobject - que es un bucket
Cómo obtener el md5sum de un archivo en Amazon''s S3 (8)
Aquí está el código para obtener S3 ETag para un objeto en PowerShell convertido de c #.
function Get-ETag {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$Path,
[Parameter(Mandatory=$true)]
[int]$ChunkSizeInMb
)
$returnMD5 = [string]::Empty
[int]$chunkSize = $ChunkSizeInMb * [Math]::Pow(2, 20)
$crypto = New-Object System.Security.Cryptography.MD5CryptoServiceProvider
[int]$hashLength = $crypto.HashSize / 8
$stream = [System.IO.File]::OpenRead($Path)
if($stream.Length -gt $chunkSize) {
$chunkCount = [int][Math]::Ceiling([double]$stream.Length / [double]$chunkSize)
[byte[]]$hash = New-Object byte[]($chunkCount * $hashLength)
$hashStream = New-Object System.IO.MemoryStream(,$hash)
[long]$numBytesLeftToRead = $stream.Length
while($numBytesLeftToRead -gt 0) {
$numBytesCurrentRead = [int][Math]::Min($numBytesLeftToRead, $chunkSize)
$buffer = New-Object byte[] $numBytesCurrentRead
$numBytesLeftToRead -= $stream.Read($buffer, 0, $numBytesCurrentRead)
$tmpHash = $crypto.ComputeHash($buffer)
$hashStream.Write($tmpHash, 0, $hashLength)
}
$returnMD5 = [System.BitConverter]::ToString($crypto.ComputeHash($hash)).Replace("-", "").ToLower() + "-" + $chunkCount
}
else {
$returnMD5 = [System.BitConverter]::ToString($crypto.ComputeHash($stream)).Replace("-", "").ToLower()
}
$stream.Close()
$returnMD5
}
Si tengo archivos existentes en el S3 de Amazon, ¿cuál es la forma más fácil de obtener su md5sum sin tener que descargar los archivos?
Gracias
Aquí está el código para obtener hash MD5 según 2017
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Base64;
public class GenerateMD5 {
public static void main(String args[]) throws Exception{
String s = "<CORSConfiguration> <CORSRule> <AllowedOrigin>http://www.example.com</AllowedOrigin> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>DELETE</AllowedMethod> <AllowedHeader>*</AllowedHeader> <MaxAgeSeconds>3000</MaxAgeSeconds> </CORSRule> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedHeader>*</AllowedHeader> <MaxAgeSeconds>3000</MaxAgeSeconds> </CORSRule> </CORSConfiguration>";
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(s.getBytes());
byte[] digest = md.digest();
StringBuffer sb = new StringBuffer();
/*for (byte b : digest) {
sb.append(String.format("%02x", b & 0xff));
}*/
System.out.println(sb.toString());
StringBuffer sbi = new StringBuffer();
byte [] bytes = Base64.encodeBase64(digest);
String finalString = new String(bytes);
System.out.println(finalString);
}
}
El código comentado es donde la mayoría de las personas lo malinterpretan, cambiándolo a hex.
ETag no parece ser MD5 para cargas múltiples (según el comentario de Gael Fraiteur). En estos casos, contiene un sufijo de menos y un número. Sin embargo, incluso el bit anterior al menos no parece ser el MD5, aunque tiene la misma longitud que un MD5. Posiblemente el sufijo es la cantidad de partes cargadas?
Esto funciona para mí En PHP, puede comparar la suma de verificación entre el archivo local y el archivo amazon usando esto:
// get localfile md5
$checksum_local_file = md5_file ( ''/home/file'' );
// compare checksum between localfile and s3file
public function compareChecksumFile($file_s3, $checksum_local_file) {
$Connection = new AmazonS3 ();
$bucket = amazon_bucket;
$header = $Connection->get_object_headers( $bucket, $file_s3 );
// get header
if (empty ( $header ) || ! is_object ( $header )) {
throw new RuntimeException(''checksum error'');
}
$head = $header->header;
if (empty ( $head ) || !is_array($head)) {
throw new RuntimeException(''checksum error'');
}
// get etag (md5 amazon)
$etag = $head[''etag''];
if (empty ( $etag )) {
throw new RuntimeException(''checksum error'');
}
// remove quotes
$checksumS3 = str_replace(''"'', '''', $etag);
// compare md5
if ($checksum_local_file === $checksumS3) {
return TRUE;
} else {
return FALSE;
}
}
He revisado jets3t y la consola de administración contra los archivos cargados ''MD5sum, y ETag parece ser igual a MD5sum. Puede ver las propiedades del archivo en la consola de administración de AWS:
Hmm ... Creo que puedes mirar el encabezado ETag. (en cuyo caso puede usar el método HTTP HEAD lugar de GET.) No lo dicen explícitamente, pero es casi seguro que Amazon usa el hash MD5 para ETag. De la documentación del Objeto PUT (no sé por qué no vienen y lo dicen):
Para garantizar que los datos no estén corruptos en la red, use el encabezado Content-MD5. Cuando utiliza el encabezado Content-MD5, Amazon S3 comprueba el objeto con el valor MD5 proporcionado. Si no coinciden, Amazon S3 devuelve un error. Además, puede calcular el MD5 al colocar un objeto en Amazon S3 y comparar el Etag devuelto con el valor calculado de MD5.
Además, los métodos SOAP le permiten solicitar solo los metadatos y no los datos en sí.
La documentación de ETag
de AWS dice:
La etiqueta de entidad es un hash del objeto. ETag refleja cambios solo en los contenidos de un objeto, no en sus metadatos. El ETag puede ser o no un resumen MD5 de los datos del objeto. Que exista o no depende de cómo se creó el objeto y de cómo se encripta como se describe a continuación:
- Los objetos creados por el objeto PUT, el objeto POST o la operación Copiar, o a través de la consola de administración de AWS, y están encriptados por SSE-S3 o texto sin formato, tienen ETags que son un resumen MD5 de sus datos de objeto.
- Los objetos creados por el objeto PUT, el objeto POST o la operación Copiar, o a través de la consola de administración de AWS, y están cifrados por SSE-C o SSE-KMS, tienen ETags que no son un resumen MD5 de sus datos de objeto.
- Si se crea un objeto mediante la operación Multipart Upload o Part Copy, el ETag no es un resumen MD5, independientemente del método de encriptación.
Referencia: http://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonResponseHeaders.html
Para cualquiera que dedique tiempo a buscar para descubrir por qué el md5 no es lo mismo que ETag en S3.
ETag calculará frente a la tirada de datos y concat todos los md5hash para hacer md5 hash de nuevo y mantener el número de fragmentos al final.
Aquí está la versión de C # para generar hash
string etag = HashOf("file.txt",8);
código fuente
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;
}