title: CloudStack: Unable to verify user credentials and/or request signature
body: <p>I am working on CloudStack API now and I have the problem about making the API request. I always got "{ "listtemplatesresponse" : {"errorcode":401,"errortext":"unable to verify user credentials and/or request signature"} }" even though I change the parameter. </p>
  
  <p>This error occurs in some commands that require the parameter and this is the command that I use:</p>
  
  <pre><code>    command=listTemplates&amp;templatefilter=featured 
  </code></pre>
  
  <p>I don't know what I did wrong since it works with others. Here is the code I use to make the API request: </p>
  
  <pre><code>    try {
          String encodedApiKey = URLEncoder.encode(apiKey.toLowerCase(), "UTF-8");
          ArrayList&lt;String&gt; sortedParams = new ArrayList&lt;String&gt;();
          sortedParams.add("apikey="+encodedApiKey);
          StringTokenizer st = new StringTokenizer(apiUrl, "&amp;");
          while (st.hasMoreTokens()) {
              String paramValue = st.nextToken().toLowerCase();
              String param = paramValue.substring(0, paramValue.indexOf("="));
              String value = URLEncoder.encode(paramValue.substring(paramValue.indexOf("=")+1, paramValue.length()), "UTF-8");
              sortedParams.add(param + "=" + value);
          }
  
          Collections.sort(sortedParams);
          System.out.println("Sorted Parameters: " + sortedParams);
          String sortedUrl = null;
          boolean first = true;
          for (String param : sortedParams) {
              if (first) {
                  sortedUrl = param;
                  first = false;
              } else {
                  sortedUrl = sortedUrl + "&amp;" + param;
              }
          }
  
          sortedUrl += "&amp;response=json";          
          System.out.println("sorted URL : " + sortedUrl);
          String encodedSignature = signRequest(sortedUrl, secretKey);
          String finalUrl = host + "?" + apiUrl + "&amp;response=json&amp;apiKey=" + apiKey + "&amp;signature=" + encodedSignature;
          StringBuilder str = new StringBuilder();
          HttpClient client = new DefaultHttpClient();
          HttpGet httpGet = new HttpGet(finalUrl);
          HttpResponse response = client.execute(httpGet);
          StatusLine statusLine = response.getStatusLine();
          int statusCode = statusLine.getStatusCode();
          if (statusCode == 200) { // Status OK
              HttpEntity entity = response.getEntity();
              InputStream content = entity.getContent();
              BufferedReader reader = new BufferedReader(new InputStreamReader(content));
              String line;
              while ((line = reader.readLine()) != null) {
                  str.append(line);
              }
              System.out.println("str: "+str);
              result = str.toString();
              System.out.println("result: "+str);
          }
          else
              System.out.println("Error response!!");
      } catch (Throwable t) {
          System.out.println(t);
      }
  </code></pre>
  
  <p>And this is signRequest function:</p>
  
  <pre><code>public static String signRequest(String request, String key) {
      try {
          Mac mac = Mac.getInstance("HmacSHA1");
          SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacSHA1");
          mac.init(keySpec);
          mac.update(request.getBytes());
          byte[] encryptedBytes = mac.doFinal();
          return URLEncoder.encode(Base64.encodeBytes(encryptedBytes), "UTF-8");
      } catch (Exception ex) {
          System.out.println(ex);
      }
      return null;
  }
  </code></pre>
  
  <p>Please feel free to ask me if you need more information. All comments and advice are welcome! </p>