我正在尝试使用apache commons HTTP Client连接到第三方应用程序API。我正在尝试连接的API是http://wiki.kayako.com/display/DEV/REST+API。
API要求我传递API密钥和签名以及用于创建签名的salt。
根据API文档,这些是创建签名的步骤
已更新
根据我得到的回复,我更改了一些代码并使用Kayako创建了一个模拟帐户来测试API
我正在使用以下类生成签名
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, 0, hmacData.length, bout);
return bout.toString("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new GeneralSecurityException(e);
}
}
}
测试api如下
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());
}
}
可以使用访问演示站点
网址:http://aruntest.kayako.com/admin/
用户:admin
密码:ty386rhjzz
当我尝试连接时,它会抛出未经授权的访问异常。
答案 0 :(得分:4)
尝试并将您的签名方法与此进行比较(可行)
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);
}
}
此次调用的结果将是您的属性签名
的值String signature = generateHmacSHA256Signature(salt, key);
qparams.add(new BasicNameValuePair("signature", signature));
生成salt / nonce的简单方法
String nonce = String.valueOf(System.currentTimeMillis());
请参阅Example:
答案 1 :(得分:1)
Kayako已使用新的java sample更新了他们的文档,该工作正常。
答案 2 :(得分:0)
我认为整个getSaltedKey()
例程是不必要的。您只是使用HMAC签署盐(它应该被称为nonce)并使用提供的密钥签名,看起来您不应该签署密钥+盐。