Cómo subir archivos de Android a Amazon S3 SIN usar el SDK
He estado trabajando en el uso de la API REST de S3 de Amazon para subir un archivo de mi dispositivo Android a un cubo que tengo. Tengo la clave y SECRET_KEY, pero no estoy seguro de cómo generar correctamente el valor signatureValue que están buscando en sus solicitudes. Estoy utilizando un HttpPut a sus servidores, pero no estoy seguro de cómo generar correctamente el valor de la firma. Hasta aquí esto es lo que tengo:
HttpPut put = new HttpPut(URL); String fmt = "EEE, dd MMM yyyy HH:mm:ss "; SimpleDateFormat format = new SimpleDateFormat(fmt, Locale.US); format.setTimeZone(TimeZone.getTimeZone("GMT")); String method = "PUT"; String contentType = "application/octet-stream"; String date = format.format(new Date()) + "GMT"; String bucket = "/test-bucket52809/"; StringBuffer buf = new StringBuffer(); buf.append(method).append("\n\n"); buf.append(contentType).append("\n"); buf.append(date).append("\n"); buf.append(bucket); String signature = percentEncodeRfc3986(hmac(buf.toString()));
Entonces aquí están los métodos que utilizo para generar el valor de la firma:
- Envío de una carga útil de notificación únicamente a GCM mediante AWS SNS
- AWS DynamoDB Recurso solicitado no encontrado
- Android AWS SDK Versión 2.2.1 - gethttprequest depricated, no puede encontrar el reemplazo
- Amazon S3 TransferListener nunca se llama
- Sube un archivo a S3 usando el SDK de AWS
private void setupMac() throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException { byte[] secretyKeyBytes = KEY_SECRET.getBytes("UTF-8"); signingKey = new SecretKeySpec(secretyKeyBytes, "HmacSHA256"); mac = Mac.getInstance("HmacSHA256"); mac.init(signingKey); } private String hmac(String stringToSign) { String signature = null; byte[] data; byte[] rawHmac; try { data = stringToSign.getBytes("UTF-8"); rawHmac = mac.doFinal(data); signature = new String(Base64.encode(rawHmac, Base64.DEFAULT)); } catch (UnsupportedEncodingException e) { throw new RuntimeException("UTF-8" + " is unsupported!", e); } return signature; } private String percentEncodeRfc3986(String s) { String out; try { out = URLEncoder.encode(s, "UTF-8").replace("+", "%20") .replace("*", "%2A").replace("%7E", "~"); } catch (UnsupportedEncodingException e) { out = s; } return out; }
Utilicé el probador de la firma de Amazon S3, y mi secuencia era correcta, pero nunca conseguí el valor codificado derecho. Gracias por cualquier ayuda o un empuje en la dirección correcta.
- Uso de SDK de Amazon Web Service para Android en Android Studio
- Cómo firmar fuera de aws cognito - android?
- Cargar una imagen de Android a Amazon S3?
- Subir archivo a Amazon S3 desde Android lento
- SSLException debido al elemento de carga para el servicio de Amazon
- El inicio de la aplicación se ralentiza: No se puede abrir '/system/framework/dpmapi.jar'
- Servidor Android más seguro y seguro backend
- Amazon AWS tutoriales?
import sun.misc.BASE64Encoder; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; String policy = (new BASE64Encoder()).encode( policy_document.getBytes("UTF-8")).replaceAll("\n","").replaceAll("\r",""); Mac hmac = Mac.getInstance("HmacSHA1"); hmac.init(new SecretKeySpec( aws_secret_key.getBytes("UTF-8"), "HmacSHA1")); String signature = (new BASE64Encoder()).encode( hmac.doFinal(policy.getBytes("UTF-8"))) .replaceAll("\n", "");
[Ref: https://aws.amazon.com/articles/1434%5D
El enlace anterior también describe los parámetros de entrada en la solicitud HTTP.
Volvería a comprobar que la fecha coincide con lo que se espera y se envía en los encabezados http (¿está configurando el "x-amz-fecha" encabezado?), Me dio un poco de dolor de cabeza al firmar solicitudes "manualmente".
Además, agregar el mensaje de error de S3 podría ayudarnos a entender lo que está mal y ayudarle.
- Android: Kernel de depuración con KGDB
- Android: Ampliación del libro de contactos del usuario. Rendimiento ContentProvider vs Sqlite vs Lista en la memoria