×

Discussion Board

Results 1 to 3 of 3

Hybrid View

  1. #1
    Registered User
    Join Date
    Nov 2012
    Posts
    47

    i have a signed request class to use amozon api in java..but i need it for j2me

    Hi friends,

    i got a signed request helper class to access amazon api for java but i dint find nything for j2me .please do help me..i will provide you the class also

    Code:
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    import java.net.URLEncoder;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.SortedMap;
    import java.util.TimeZone;
    import java.util.TreeMap;
    
    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    
    import org.apache.http.util.EncodingUtils;
    
    /**
     * This class contains all the logic for signing requests
     * to the Amazon Product Advertising API.
     */
    public class SignedRequestsHelper {
        /**
         * All strings are handled as UTF-8
         */
        private static final String UTF8_CHARSET = "UTF-8";
        
        /**
         * The HMAC algorithm required by Amazon
         */
        private static final String HMAC_SHA256_ALGORITHM = "HmacSHA256";
        
        /**
         * This is the URI for the service, don't change unless you really know
         * what you're doing.
         */
        private static final String REQUEST_URI = "/onca/xml";
        
        /**
         * The sample uses HTTP GET to fetch the response. If you changed the sample
         * to use HTTP POST instead, change the value below to POST. 
         */
        private static final String REQUEST_METHOD = "GET";
    
        private String endpoint = null;
        private String awsAccessKeyId = null;
        private String awsSecretKey = null;
    
        private SecretKeySpec secretKeySpec = null;
        private Mac mac = null;
    
        /**
         * You must provide the three values below to initialize the helper.
         *  
         * @param endpoint          Destination for the requests.
         * @param awsAccessKeyId    Your AWS Access Key ID
         * @param awsSecretKey      Your AWS Secret Key
         */
        public static SignedRequestsHelper getInstance(
                String endpoint, 
                String awsAccessKeyId, 
                String awsSecretKey
        ) throws IllegalArgumentException, UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException
        {
            if (null == endpoint || endpoint.length() == 0)
                { throw new IllegalArgumentException("endpoint is null or empty"); }
            if (null == awsAccessKeyId || awsAccessKeyId.length() == 0) 
                { throw new IllegalArgumentException("awsAccessKeyId is null or empty"); }
            if (null == awsSecretKey || awsSecretKey.length() == 0)   
                { throw new IllegalArgumentException("awsSecretKey is null or empty"); }
            
            SignedRequestsHelper instance = new SignedRequestsHelper();
            instance.endpoint = endpoint.toLowerCase();
            instance.awsAccessKeyId = awsAccessKeyId;
            instance.awsSecretKey = awsSecretKey;
    
            byte[] secretyKeyBytes = instance.awsSecretKey.getBytes(UTF8_CHARSET);
            instance.secretKeySpec = new SecretKeySpec(secretyKeyBytes, HMAC_SHA256_ALGORITHM);
            instance.mac = Mac.getInstance(HMAC_SHA256_ALGORITHM);
            instance.mac.init(instance.secretKeySpec);
    
            return instance;
        }
        
        /**
         * The construct is private since we'd rather use getInstance()
         */
        private SignedRequestsHelper() {}
    
        /**
         * This method signs requests in hashmap form. It returns a URL that should
         * be used to fetch the response. The URL returned should not be modified in
         * any way, doing so will invalidate the signature and Amazon will reject
         * the request.
         */
        public String sign(Map<String, String> params) {
            // Let's add the AWSAccessKeyId and Timestamp parameters to the request.
            params.put("AWSAccessKeyId", this.awsAccessKeyId);
            params.put("Timestamp", this.timestamp());
    
            // The parameters need to be processed in lexicographical order, so we'll
            // use a TreeMap implementation for that.
            SortedMap<String, String> sortedParamMap = new TreeMap<String, String>(params);
            
            // get the canonical form the query string
            String canonicalQS = this.canonicalize(sortedParamMap);
            
            // create the string upon which the signature is calculated 
            String toSign = 
                REQUEST_METHOD + "\n" 
                + this.endpoint + "\n"
                + REQUEST_URI + "\n"
                + canonicalQS;
    
            // get the signature
            String hmac = this.hmac(toSign);
            String sig = this.percentEncodeRfc3986(hmac);
    
            // construct the URL
            String url = 
                "http://" + this.endpoint + REQUEST_URI + "?" + canonicalQS + "&Signature=" + sig;
    
            return url;
        }
    
        /**
         * This method signs requests in query-string form. It returns a URL that
         * should be used to fetch the response. The URL returned should not be
         * modified in any way, doing so will invalidate the signature and Amazon
         * will reject the request.
         */
        public String sign(String queryString) {
            // let's break the query string into it's constituent name-value pairs
            Map<String, String> params = this.createParameterMap(queryString);
            
            // then we can sign the request as before
            return this.sign(params);
        }
    
        /**
         * Compute the HMAC.
         *  
         * @param stringToSign  String to compute the HMAC over.
         * @return              base64-encoded hmac value.
         */
        private String hmac(String stringToSign) {
            String signature = null;
            byte[] data;
            byte[] rawHmac;
            try {
                data = stringToSign.getBytes(UTF8_CHARSET);
                rawHmac = mac.doFinal(data);
                Base64Coder encoder = new Base64Coder();
                signature = new String(encoder.encode(rawHmac));
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(UTF8_CHARSET + " is unsupported!", e);
            }
            return signature;
        }
    
        /**
         * Generate a ISO-8601 format timestamp as required by Amazon.
         *  
         * @return  ISO-8601 format timestamp.
         */
        private String timestamp() {
            String timestamp = null;
            Calendar cal = Calendar.getInstance();
            DateFormat dfm = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
            dfm.setTimeZone(TimeZone.getTimeZone("GMT"));
            timestamp = dfm.format(cal.getTime());
            return timestamp;
        }
    
        /**
         * Canonicalize the query string as required by Amazon.
         * 
         * @param sortedParamMap    Parameter name-value pairs in lexicographical order.
         * @return                  Canonical form of query string.
         */
        private String canonicalize(SortedMap<String, String> sortedParamMap) {
            if (sortedParamMap.isEmpty()) {
                return "";
            }
    
            StringBuffer buffer = new StringBuffer();
            Iterator<Map.Entry<String, String>> iter = sortedParamMap.entrySet().iterator();
    
            while (iter.hasNext()) {
                Map.Entry<String, String> kvpair = iter.next();
                buffer.append(percentEncodeRfc3986(kvpair.getKey()));
                buffer.append("=");
                buffer.append(percentEncodeRfc3986(kvpair.getValue()));
                if (iter.hasNext()) {
                    buffer.append("&");
                }
            }
            String cannoical = buffer.toString();
            return cannoical;
        }
    
        /**
         * Percent-encode values according the RFC 3986. The built-in Java
         * URLEncoder does not encode according to the RFC, so we make the
         * extra replacements.
         * 
         * @param s decoded string
         * @return  encoded string per RFC 3986
         */
        private String percentEncodeRfc3986(String s) {
            String out;
            try {
                out = URLEncoder.encode(s, UTF8_CHARSET)
                    .replace("+", "%20")
                    .replace("*", "%2A")
                    .replace("%7E", "~");
            } catch (UnsupportedEncodingException e) {
                out = s;
            }
            return out;
        }
    
        /**
         * Takes a query string, separates the constituent name-value pairs
         * and stores them in a hashmap.
         * 
         * @param queryString
         * @return
         */
        private Map<String, String> createParameterMap(String queryString) {
            Map<String, String> map = new HashMap<String, String>();
            String[] pairs = queryString.split("&");
    
            for (String pair: pairs) {
                if (pair.length() < 1) {
                    continue;
                }
    
                String[] tokens = pair.split("=",2);
                for(int j=0; j<tokens.length; j++)
                {
                    try {
                        tokens[j] = URLDecoder.decode(tokens[j], UTF8_CHARSET);
                    } catch (UnsupportedEncodingException e) {
                    }
                }
                switch (tokens.length) {
                    case 1: {
                        if (pair.charAt(0) == '=') {
                            map.put("", tokens[0]);
                        } else {
                            map.put(tokens[0], "");
                        }
                        break;
                    }
                    case 2: {
                        map.put(tokens[0], tokens[1]);
                        break;
                    }
                }
            }
            return map;
        }
    }
    can any one make thising useful for j2me

    Regards rahul

  2. #2
    Super Contributor
    Join Date
    Nov 2003
    Location
    Bangalore , India
    Posts
    4,430

    Re: i have a signed request class to use amozon api in java..but i need it for j2me

    Most of the packages mentioned are not available for JavaME, either you have to look for an already existing port or you have to port it yourself.

    Regards
    Gopal

  3. #3
    Super Contributor
    Join Date
    Jun 2003
    Location
    Cheshire, UK
    Posts
    7,395

    Re: i have a signed request class to use amozon api in java..but i need it for j2me

    Gopal is right... you need to re-write this for Java MIDP, almost completely. Even the grammar is wrong, as it's Java 5, and you have to re-write is as Java 2 (so, no generics).

    For the encryption, you are going to need BouncyCastle.

    You're also likely to have to port the Apache HTTP utils EncodingUtils class.

    This is not a five minute job...

Similar Threads

  1. How to request All-Files capability in Open Signed Offline?
    By sophiagg in forum Symbian Signed Support, Application Packaging and Distribution and Security
    Replies: 7
    Last Post: 2012-02-27, 10:17
  2. How can i request 1 signed or certified from Nokia ?
    By thanhlnh in forum Mobile Java General
    Replies: 1
    Last Post: 2011-11-09, 04:22
  3. Does no one handle the request e-mail to symbian.signed@nokia.com?
    By inter_fan in forum Symbian Signed Support, Application Packaging and Distribution and Security
    Replies: 6
    Last Post: 2011-06-24, 06:41
  4. Midlet to call a j2me java class
    By kakinyim in forum Mobile Java General
    Replies: 5
    Last Post: 2011-05-18, 20:25
  5. Open Signed - Request fails
    By srinidhirao in forum Symbian Signed Support, Application Packaging and Distribution and Security
    Replies: 1
    Last Post: 2009-06-15, 06:06

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •