Amazon Services
Amazon Marketplace Web Service (Amazon MWS) Documentation
Amazon MWS Documentation

Working with Content-MD5 checksums

MD5 is an algorithm for computing a 128-bit "digest" (or hash) of arbitrary-length data with a high degree of confidence that any alterations in the data will be reflected in alterations in the digest. You must include a Content-MD5 hash when you submit a feed . You should pass the hash as the ContentMD5Value parameter. For backwards compatibilty, you can pass the hash as a Content-MD5 header, but using the ContentMD5Value parameter is more secure.

Amazon Marketplace Web Service (Amazon MWS) calculates the MD5 checksum and compares it to the hash value you sent to ensure that the received feed has not been corrupted in transmission. The process is reversed when Amazon MWS sends a report; the Content-MD5 header is sent with the report and you calculate the MD5 checksum and compare it to the header Amazon sent to make sure the report you received has not been corrupted in transmission.

The basic process for sending a feed with a Content-MD5 hash to Amazon MWS is as follows:
  1. Store the feed to be submitted on disk before transmitting it to Amazon MWS.
  2. Compute the Content-MD5 of the file and store it in a companion file.
  3. Create a SubmitFeed request, pass the stored Content-MD5 as the ContentMD5Value parameter, and attach the file contents in a stream.
  4. Submit the request.

The following Java code sample illustrates how to compute the Content-MD5 value for a feed submitted to Amazon:

/**
 * Calculate content MD5 hash values for feeds stored on disk.
 */
public static String computeContentMD5Value( FileInputStream fis ) 
    throws IOException, NoSuchAlgorithmException {

    DigestInputStream dis = new DigestInputStream( fis,
        MessageDigest.getInstance( "MD5" ));

    byte[] buffer = new byte[8192];
    while( dis.read( buffer ) > 0 );

    String md5Content = new String(
        org.apache.commons.codec.binary.Base64.encodeBase64(
            dis.getMessageDigest().digest()) ); 

    // Effectively resets the stream to be beginning of the file
    // via a FileChannel.
    fis.getChannel().position( 0 );

    return md5Content;
}

The following Java code sample illustrates how to compute the MD5 checksum for a report that is downloaded:

/**
 * Consume the stream and return its Base-64 encoded MD5 checksum.
 */
public static String computeContentMD5Header(InputStream inputStream) {
    // Consume the stream to compute the MD5 as a side effect.
    DigestInputStream s;
    try {
        s = new DigestInputStream(inputStream,
                                  MessageDigest.getInstance("MD5"));
        // drain the buffer, as the digest is computed as a side-effect
        byte[] buffer = new byte[8192];
        while(s.read(buffer) > 0);
        return new String(
            org.apache.commons.codec.binary.Base64.encodeBase64(
                s.getMessageDigest().digest()),
                "UTF-8");
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

The following example shows an MD5 string in an http request using the POST method. The string is inserted immediately after the last parameter statement.

POST /Feeds/2009-01-01 HTTP/1.1
Content-Type: x-www-form-urlencoded
Host: mws.amazonservices.com
User-Agent: <Your User Agent Header>

?AWSAccessKeyId=0PB842ExampleN4ZTR2
&Action=SubmitFeed
&FeedType=_POST_PRODUCT_DATA_
&MWSAuthToken=amzn.mws.4ea38b7b-f563-7709-4bae-87aeaEXAMPLE
&MarketplaceIdList.Id.1=ATVExampleDER
&SellerId=A1XExample5E6
&ContentMD5Value=ExampleMd5HashOfHttpBodyAsPerRfc2616Example
&SignatureMethod=HmacSHA256
&SignatureVersion=2
&Timestamp=2009-01-26T23%3A51%3A31.315Z
&Version=2009-01-01
&Signature=SvSExamplefZpSignaturex2cs%3D
Note:

Previously, Amazon MWS accepted the MD5 hash as a Content-MD5 header instead of a parameter. Passing it as a parameter ensures that the MD5 value is part of the method signature, which prevents anyone on the network from tampering with the feed content.

Amazon MWS will still accept a Content-MD5 header whether or not a ContentMD5Value parameter is included. If both a header and parameter are used, and they do not match, you will receive an InvalidParameterValue error.