Java – how to create a signature using hmacsha1 and a key to connect to the Kayako API

I'm trying to connect to a third-party application API using Apache commons HTTP client The API I'm trying to connect to is http://wiki.kayako.com/display/DEV/REST +API.

The API requires me to pass the API key and signature, as well as the salt used to create the signature

According to the API documentation, these are the steps to create a signature

>Generate a random string to create salt (in PHP, you will use mt_and() to do this) > generate a signature by using sha256 hash salt, And use the key as the key (in PHP, you will use hash_hmac() to do this) > Base64 encoded signature (in PHP, you will use base64_encode() to do this) > URL encoded output (in PHP, you will use urlencode() to do this)

to update

According to the reply I received, I changed some code and created a mock account with Kayako to test the API

I am using the following classes to generate signatures

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.GeneralSecurityException;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.util.encoders.Base64Encoder;

public class GenSign2 {
    public static void main(String[] args) throws GeneralSecurityException,IOException {
        String secretKey = "M2Y2YjkxZDEtYmNlOC1mYmI0LTkxZTgtOTNiY2RiMDhmN2E2YjExNGUwYjktNGJkYy1jZTM0LWQ1MWYtZGIwYWRlZTE0NGNh";
        String salt = "0123456789";

        String generateHmacSHA256Signature = generateHmacSHA256Signature(salt,secretKey);
        System.out.println("Signature: " + generateHmacSHA256Signature);

        String urlEncodedSign = URLEncoder.encode(generateHmacSHA256Signature,"UTF-8");

        System.out.println("Url encoded value: " + urlEncodedSign);
    }

    public static String generateHmacSHA256Signature(String data,String key)
            throws GeneralSecurityException,IOException {
        byte[] hmacData = null;

        try {
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"),"HmacSHA256");
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(secretKey);
            hmacData = mac.doFinal(data.getBytes("UTF-8"));
            ByteArrayOutputStream bout = new ByteArrayOutputStream();

            new Base64Encoder().encode(hmacData,hmacData.length,bout);
            return bout.toString("UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new GeneralSecurityException(e);
        }
    }
}

The test API is as follows

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

public class TestApi {

    public static void main(String[] args) throws ClientProtocolException,IOException,URISyntaxException {
        HttpClient client = new DefaultHttpClient();

        List<NameValuePair> qparams = new ArrayList<NameValuePair>();
        qparams.add(new BasicNameValuePair("apikey","f165dc40-ce3f-6864-7d5e-27a7188b2e62"));
        qparams.add(new BasicNameValuePair("salt","0123456789"));
        qparams.add(new BasicNameValuePair("signature","mbrhpXkP0LzNMNDygHAorqMx%2FDGovl%2FauMTOMB6RNMA%3D"));

        HttpPost httpget = new HttpPost(
                "http://aruntest.kayako.com/api/index.PHP?e=/Core/Test");

        HttpResponse response = client.execute(httpget);
        System.out.println(response.getProtocolVersion());
        System.out.println(response.getStatusLine().getStatusCode());
        System.out.println(response.getStatusLine().getReasonPhrase());
        System.out.println(response.getStatusLine().toString());
    }

}

You can access the demo site using: http://aruntest.kayako.com/admin/ User: admin Password: ty386rhjzz

When I try to connect, it throws an unauthorized access exception

Solution

Try and compare your signature method to this one (it works)

public static String generateHmacSHA256Signature(String data,String key)   throws GeneralSecurityException {
    byte[] hmacData = null;

    try {
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"),"HmacSHA256");
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(secretKey);
        hmacData = mac.doFinal(data.getBytes("UTF-8"));
        return new BASE64Encoder().encode(hmacData);
    } catch (UnsupportedEncodingException e) {
        // TODO: handle exception
        throw new GeneralSecurityException(e);
    }
}

The result of this call will be the value of your property signature

String signature = generateHmacSHA256Signature(salt,key);
qparams.add(new BasicNameValuePair("signature",signature));

A simple way to generate salt / nonce

String nonce = String.valueOf(System.currentTimeMillis());

See example:

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>