title: How to upload files from Android to Amazon S3 WITHOUT using the SDK
body: <p>I've been working on using the REST API of Amazon's S3 to upload a file from my Android device to a bucket I have. I have the KEY and SECRET_KEY, but am not sure how to properly generate the signatureValue they are looking for in their requests. I'm using a HttpPut to their servers, but am not sure how to properly generate the signatureValue. So far here's what I have:</p>
  
  <pre><code>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()));
  </code></pre>
  
  <p>Then here are the methods I use to generate the signature value:</p>
  
  <pre><code>    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;
      }
  </code></pre>
  
  <p>I used the Amazon S3 Signature tester, and my string was correct, but I never got the right encoded value. Thanks for any help or a push in the right direction.</p>