我正在尝试使用apache commons HTTP Client连接到第三方应用程序API.我正在尝试连接的API是
http://wiki.kayako.com/display/DEV/REST+API.
API要求我传递API密钥和签名以及用于创建签名的salt.
根据API文档,这些是创建签名的步骤
>生成随机字符串以创建salt(在PHP中,您将使用mt_and()来执行此操作)
>通过使用SHA256散列盐来生成签名,并使用密钥作为密钥(在PHP中,您将使用hash_hmac()来执行此操作)
> base64编码签名(在PHP中,你将使用base64_encode()来执行此操作)
> URL编码输出(在PHP中,您将使用urlencode()来执行此操作)
更新
根据我得到的回复,我更改了一些代码并使用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,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
当我尝试连接时,它会抛出未经授权的访问异常.
解决方法
尝试并将您的签名方法与此进行比较(它有效)
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));
String nonce = String.valueOf(System.currentTimeMillis());