code: private String sign(Map<String, String> params, String apiSecret) throws JinxException {
      StringBuilder authSb = new StringBuilder(apiSecret);
      for (String key : params.keySet()) {
        authSb.append(key).append(params.get(key));
      }
  
      String apiSig;
      try {
        MessageDigest m = MessageDigest.getInstance("MD5");
        m.reset();
        m.update(authSb.toString().getBytes(JinxConstants.UTF8));
        byte[] digest = m.digest();
        apiSig = JinxUtils.toHexString(digest);
      } catch (Exception e) {
        throw new JinxException("Error computing MD5 value.", e);
      }
  
      return apiSig;
    }
docs: /*
  Compute the signature for the API call.
  <br>
  This computes a signature for the legacy Flickr auth API. The only time we should need to call this
  is when converting a legacy access token to an OAuth access token.
  <br>
  Legacy auth spec: http://secure.flickr.com/services/api/auth.spec.html
  
  @param params    key/value map of parameters. Must be in alphabetic order to
  conform to signing rules.
  @param apiSecret application API secret.
  @return MD5 hash for the parameters.
  @throws JinxException if there are any errors.