I'm trying to change a working example from C sharp to Java but i'm struggling and don't know where the problem is. I contacted Kraken and they advised me that I have the wrong signature... The response is:
{"error":["EAPI:Invalid signature"]}
Here's the C sharp version:
private JsonObject QueryPrivate(string a_sMethod, string props = null)
{
// generate a 64 bit nonce using a timestamp at tick resolution
Int64 nonce = DateTime.Now.Ticks;
props = "nonce=" + nonce + props;
string path = string.Format("/{0}/private/{1}", _version, a_sMethod);
string address = _url + path;
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(address);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
webRequest.Headers.Add("API-Key", _key);
byte[] base64DecodedSecred = Convert.FromBase64String(_secret);
var np = nonce + Convert.ToChar(0) + props;
var pathBytes = Encoding.UTF8.GetBytes(path);
var hash256Bytes = sha256_hash(np);
var z = new byte[pathBytes.Count() + hash256Bytes.Count()];
pathBytes.CopyTo(z, 0);
hash256Bytes.CopyTo(z, pathBytes.Count());
var signature = getHash(base64DecodedSecred, z);
webRequest.Headers.Add("API-Sign", Convert.ToBase64String(signature));
if (props != null)
{
using (var writer = new StreamWriter(webRequest.GetRequestStream()))
{
writer.Write(props);
}
}
//Make the request
try
{
using (WebResponse webResponse = webRequest.GetResponse())
{
using (Stream str = webResponse.GetResponseStream())
{
using (StreamReader sr = new StreamReader(str))
{
return (JsonObject)JsonConvert.Import(sr);
}
}
}
}
}
The full code is here at:
https://bitbucket.org/arrivets/krakenapi/src/cff138b017c38efde2db1a080fb765790a6d04c8/KrakenClient/KrakenClient.cs?at=master&fileviewer=file-view-default
Here is my Java version:
private void fetch() throws UnsupportedEncodingException, IOException, NoSuchAlgorithmException {
String version = "0";
String key = ".....6";
String secret = "....g==";
long nonce = System.currentTimeMillis();
String props = null;
props = "nonce=" + nonce + props; // I've tried this with and without the 'null' on the end
// url
String url = "https://api.kraken.com";
String path = "/" + version + "/private/" + "Balance";
String address = url + path;
// post req
HttpPost httpPost = new HttpPost(address);
// headers
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpPost.setHeader("API-Key", key);
// decode buffer
BASE64Decoder decoder = new BASE64Decoder();
byte[] base64DecodedSecred = decoder.decodeBuffer(secret);
// nonce & props
String np = nonce + (char) 0 + props;
// create byte array
byte[] pathBytes = path.getBytes("UTF-8");
byte[] hash256Bytes = sha256(np);
byte[] z = new byte[pathBytes.length + hash256Bytes.length];
System.arraycopy(pathBytes, 0, z, 0, pathBytes.length);
System.arraycopy(hash256Bytes, 0, z, pathBytes.length, hash256Bytes.length);
// encrypt signature
byte[] signature = hmacEncrypt(z, base64DecodedSecred); // my hmacEncrypt is message, secret (opposite to the c sharp)
BASE64Encoder encoder = new BASE64Encoder();
httpPost.setHeader("API-Sign", encoder.encode(signature));
// Post
List<NameValuePair> nvps = new ArrayList<>();
nvps.add(new BasicNameValuePair("nonce", String.valueOf(nonce)));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
// Client & Response
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
// parse
JsonParser jp = new JsonParser();
JsonElement root = jp.parse(EntityUtils.toString(entity));
System.out.println(root); // {"error":["EAPI:Invalid signature"]}
// close client
httpClient.close();
}
I'm sorry to have posted a large bits of code, any help would be appreciated. Thank you!
there is no cchmac 512 encryption in your code. that is why you get this EAPI:Invalid signature"
Related
would appreciate any help to fix it with some detailed explanation , one of the solution saying to use Digest authentication, if it's correct, how do we use in the below code, the error pointed to "httppost.setHeader("Authorization", "Basic " + encoding);" this line
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
String encoding;
LOGGER.info("Entered into try");
if (direction != null && direction.equalsIgnoreCase(ASPERA_DIRECTION_DOWNLOAD)) {
LOGGER.info("entered if");
url = acceleratorUtilConfig.getAccelDownloadSetupUrl();
path = acceleratorUtilConfig.getS3DownloadRootPath() + path;
encoding = new String(Base64.encodeBase64((acceleratorUtilConfig.getAccelDownloadAccessKey() + ":" + acceleratorUtilConfig.getAccelDownloadSecret()).getBytes()));
} else {
LOGGER.info("entered else");
url = acceleratorUtilConfig.getAccelUploadSetupUrl();
path = acceleratorUtilConfig.getS3UploadRootPath() + path;
encoding = new String(Base64.encodeBase64((acceleratorUtilConfig.getAccelUploadAccessKey() + ":" + acceleratorUtilConfig.getAccelUploadSecret()).getBytes()));
}
LOGGER.debug("GenerateToken : {} : {}", url, path);
LOGGER.debug(": {}", encoding);
LOGGER.debug(" : {} : {}", direction, filePathArray);
LOGGER.debug("NewGenerateToken : {}", acceleratorUtilConfig.getAccelDownloadSetupUrl());
TokenRequest tokreq = new TokenRequest(
Stream.of(new TransferRequest(new TransferRequestAttribute(true, "always", direction, path,
pathModel.getPathList(filePathArray), null), null)).collect(Collectors.toList()),
null);
ObjectMapper mapper = new ObjectMapper();
String inJson = "";
inJson = mapper.writeValueAsString(tokreq);
HttpPost httppost = new HttpPost(url);
httppost.setHeader("Authorization", "Basic " + encoding);
StringEntity input = new StringEntity(inJson);
httppost.setEntity(input);
LOGGER.debug("GenerateToken : Request sent");
HttpResponse response1 = httpClient.execute(httppost);
LOGGER.debug("GenerateToken : response returned");
so learning still but i'm getting an Error 401 unauthorised back from the code below. I know that the OAuth header works as it works in postman so i'm assuming there is a problem with the POST request / Auth header? Any ideas?
//set timestamp
Long timestamp = System.currentTimeMillis()/1000;
//set nonce ***** call from main system*************************************************************
String aString = randomAlphaNumeric(11);
// other stuff
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
String url = "aURL";
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
// String auth = Base64.getEncoder().encodeToString(credentials.getBytes());
List<NameValuePair> oauthHeaders = new ArrayList<>(9);
oauthHeaders.add(new BasicNameValuePair("oauth_consumer_key", "aKey"));
oauthHeaders.add(new BasicNameValuePair("oauth_nonce", aString));
oauthHeaders.add(new BasicNameValuePair("oauth_timestamp", String.valueOf(timestamp)));
oauthHeaders.add(new BasicNameValuePair("oauth_signature_method", "HMAC-SHA1"));
oauthHeaders.add(new BasicNameValuePair("oauth_version", "1.0"));
//generate signature
//encode
String encodedURL = encode(oauthHeaders.toString());
System.out.println("encoded URL:" +encodedURL);
//form base string
String baseString = "POST&"+encode(url).toString()+encodedURL;
System.out.println("Base String: "+baseString);
//form signature
byte[] byteHMAC = null;
try {
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec spec;
if (null == secretKey) {
String signingKey = encode(secretKey) + '&';
spec = new SecretKeySpec(signingKey.getBytes(), "HmacSHA1");
} else {
String signingKey = encode(secretKey) + '&' + encode(secretKey);
spec = new SecretKeySpec(signingKey.getBytes(), "HmacSHA1");
}
mac.init(spec);
byteHMAC = mac.doFinal(baseString.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
String signature = new BASE64Encoder().encode(byteHMAC);
System.out.println("oauth signature: "+signature);
//set signature to params
oauthHeaders.add(new BasicNameValuePair("oauth_signature", signature));
String test = "OAuth "+oauthHeaders.toString();
headers.set("Authorization", test);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("Name",name.toString());
map.add("Region",region.toString());
HttpEntity<MultiValueMap<String, String>> requestEntity= new HttpEntity<MultiValueMap<String, String>>(headers, map);
System.out.println(requestEntity);
ResponseEntity<String> response= restTemplate.exchange(url ,HttpMethod.POST, requestEntity, String.class);
System.out.println(response.toString());
HttpStatus status = response.getStatusCode();
status.toString();
if(status.equals("200")){
Notification.show("Employer" + name +" added successfully");
}
else{
Notification.show("Unsuccessful, error: "+status);
}
}
removed the URL and consumer key / signature for obvious reasons.
The following System out prints might help as well:
encoded params:
%5Boauth_consumer_key%3aKey%2C%20oauth_nonce%3DWZU8H1B5JA6%2C%20oauth_timestamp%3D1511621759%2C%20oauth_signature_method%3DHMAC-SHA1%2C%20oauth_version%3D1.0%5D
Base String: POST&https%3A%2F%2Fapi.test.payrun.io%2FEmployer%5Boauth_consumer_key%3aKey%2C%20oauth_nonce%3DWZU8H1B5JA6%2C%20oauth_timestamp%3D1511621759%2C%20oauth_signature_method%3DHMAC-SHA1%2C%20oauth_version%3D1.0%5D
oauth signature: DlRJGSzgRIItzz+LzMbgnIfbOqU=
The value of oauth_signature is wrong. You are using asignature as the value of oauth_signature, but you have to compute the correct value for your request and set it to oauth_signature. If the value of oauth_signature is wrong, the server will reject your request. See "3.4. Signature" in RFC 5849 (The OAuth 1.0 Protocol) for details.
For anyone who wants to make this work then please see below for a complete OAuth Generator example :):
public class oAuthGenerator {
private String httpMethod;
private String params;
private String url;
//Required for percent encoding
private static final String ENC = "ASCII";
//Required for nonce
private static final String ALPHA_NUMERIC_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
//As provided by Payrun.io
private static final String secretKey = "aSecretKey";
//As provided by Payrun.io
private static final String consumerKey ="aConsumerKey";
private List veriList;
//Constructor for setting signature base string values.
//#Param url needs to be percent encoded
//#Param params needs to be percent encoded, this is done #Method generateOAuth()
public oAuthGenerator(String httpMethod,String url )throws Exception {
veriList= new ArrayList<String>();
veriList.add("POST");
veriList.add("GET");
veriList.add("PUT");
veriList.add("DELETE");
if (veriList.contains(httpMethod)){
this.httpMethod = httpMethod+"&";}
this.url = URLEncoder.encode(url,ENC)+"&";
}
//A method used to generate the OAuth Authorization header
//#Method randomAlphaNumeric() calls internal method using instance variable ALPHA_NUMERIC_STRING
//#Method getSignature() returns String HMACSHA1 > Base64 encoded value of httpMethod,url,params
public String generateOAuth()throws Exception{
//Set timestamp as seconds from 01-01-1970
Timestamp timestamp = new Timestamp(System.currentTimeMillis()/1000);
Long aTimestamp = timestamp.getTime();
//Set nonce which is a 10 digit random, non repeating alpha-numeric value
String aNonce = randomAlphaNumeric(10);
//Normalize and form param string
String normalizedParams = "oauth_consumer_key="+consumerKey+"&"+"oauth_nonce="+aNonce+"&"+"oauth_signature_method="+"HMAC-SHA1"+"&"+"oauth_timestamp="+ aTimestamp.toString()+"&"+"oauth_version="+"1.0";
//Percent encoded params
params = URLEncoder.encode(normalizedParams,ENC);
//Set signature variable
String signature = getSignature();
//place into required format
String oAuthResult = "OAuth "+"oauth_version="+"\"1.0\""+","+"oauth_consumer_key="+"\"" + consumerKey + "\""+","+"oauth_signature_method="+"\"HMAC-SHA1\""+","+"oauth_timestamp="+"\""+aTimestamp+"\""+","+"oauth_nonce="+"\""+aNonce+"\""+","+"oauth_signature="+"\""+signature+"\"";
return oAuthResult;
}
// A method designed to return a hashed and base64 encoded value.
//#Param aString holds HMAC-SHA1 and Base 64 encoded value of variables httpMethod,url,params
//#Param result holds percent encoded value of aString
private String getSignature()
throws Exception {
//form base string
StringBuilder base = new StringBuilder();
base.append(httpMethod);
base.append(url);
base.append(params);
//Set SecretKey of variable secretKey using HMAC-SHA1 algorithm
SecretKey signingKey = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
// Get an hmac_sha1 Mac instance and initialize with the signing key
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
// Compute the hmac on input data bytes, then encode to Base64
String aString = Base64.getEncoder().encodeToString(mac.doFinal(base.toString().getBytes(ENC))).trim();
//Percent encoded the Base64 value
String result = URLEncoder.encode(aString, ENC);
return new String(result);
}
//Required for nonce, returns a random alpha numeric value by using variable ALPHA_NUMERIC_STRING
private static String randomAlphaNumeric(int count) {
StringBuilder builder = new StringBuilder();
while (count-- != 0) {
int character = (int)(Math.random()*ALPHA_NUMERIC_STRING.length());
builder.append(ALPHA_NUMERIC_STRING.charAt(character));
}
return builder.toString();
}
}
I have a servlet that gives the clients many files in one request.
I put files(image,pdf,...) or other data (like json,...) as byte array in the response :
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
ByteArrayBody pic1 = new ByteArrayBody(imageBytes1, "pic1.png");
ByteArrayBody pic2 = new ByteArrayBody(imageBytes2, "pic2.png");
builder.addPart("img1", pic1);
builder.addPart("img2", pic2);
StringBody sb = new StringBody(responseJson.toString(),ContentType.APPLICATION_JSON);
builder.addPart("projectsJson", sb);
String boundary = "***************<<boundary>>****************";
builder.setBoundary(boundary);
HttpEntity entity = builder.build();
entity.writeTo(response.getOutputStream());
I get the response (in the client side) like :
String body = EntityUtils.toString(response.getEntity());
System.out.println("body : " + body);
and the body is :
--***************<<boundary>>****************
Content-Disposition: form-data; name="pdf1"; filename="test2"
Content-Type: application/octet-stream
%PDF-1.5
%����
3 0 obj
<< /Length 4 0 R
/Filter /FlateDecode
>>
stream
x��Zۊ��}����&�7��`����a����,��3���wDd�.]R����4�V+��q���r���r��EJ�wܝC�>��}}���}>A�?_�>\]��W߾����#��.D'��������w؝q|��ٯ�ޝw����s�z0��?&o�<�"z�!�7ca�)���Q�&U��nJ��#��]c#�N���}H��&��4U�0'D���~F
..
..
..
--***************<<boundary>>****************
Content-Disposition: form-data; name="img1"; filename="fgfgf"
Content-Type: image/png
�����JFIF��H�H����o�Exif��II*��������������������������������������������(�������1��������2���������������i������Q��%������S���T��Sony�E6833�H������H������32.0.A.6.170_0_f500�2015:11:14 12:09:58������u ������v ������x �����y �����z ��������,��������4��'���������������0220�����<�������P���ʿb �����c �����d �����f ������g ������h ������i ������j ������k ������l �����m �����n �����o ��#���p ��*���q ��,���r ��)���s ��#���t �����u �����v �����w ������x ������y ������z ������{ ������| ������~ ����� ������ �����Q������������������������
���#�����
..
..
..
How can i extract data`s (images , pdf , json , ... ) from response.
please help me.
thanks.
Possible, Apache FileUpload will help you. We use it in servlets for upload files.
I use the javax.mail API.
For test :
ByteArrayDataSource ds = new ByteArrayDataSource (response.getEntity().getContent(), "multipart/mixed");
MimeMultipart multipart = new MimeMultipart(ds);
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
System.out.println("body : " + bodyPart.getFileName());
System.out.println("body : " + bodyPart.getContentType());
DataHandler handler = bodyPart.getDataHandler();
System.out.println("handler : " + handler.getName());
System.out.println("handler : " + handler.getContentType());
String curContentType = handler.getContentType();
if (curContentType.equalsIgnoreCase("application/json")) {
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
handler.writeTo(arrayOutputStream);
System.out.println("projectsJson : " + arrayOutputStream);
} else {
OutputStream outputStream = null;
String ext = "";
if (curContentType.equalsIgnoreCase("image/gif")) {
ext = ".gif";
} else if (curContentType.equalsIgnoreCase("image/jpeg")) {
ext = ".jpg";
}else if (curContentType.equalsIgnoreCase("image/png")) {
ext = ".png";
} else if (curContentType.equalsIgnoreCase("image/bmp")) {
ext = ".bmp";
} else if (curContentType.equalsIgnoreCase("application/pdf")
|| (curContentType.equalsIgnoreCase("application/x-pdf"))) {
ext = ".pdf";
}
outputStream = new FileOutputStream(handler.getName()+ext);
handler.writeTo(outputStream);
outputStream.flush();
outputStream.close();
}
}
This works good.
Also You can use Apache FileUpload.
for test :
byte[] bodyarr = toByteArr(response.getEntity().getContent());
byte[] boundary = "*************boundary>>****************".getBytes();
ByteArrayInputStream bis = new ByteArrayInputStream(bodyarr);
MultipartStream stream;
stream = new MultipartStream(bis,boundary);
boolean hasNextPart = stream.skipPreamble();
while (hasNextPart) {
String header=stream.readHeaders();
String name = getNameFromHeader(header);
//if data is image
FileOutputStream outputStream = new FileOutputStream(name+".png");
stream.readBodyData(outputStream);
hasNextPart = stream.readBoundary();
}
Enjoy.
Below is the Http post method for file upload in c#. What is the equivalent for this code in java which uses apache library. How to add contentDisposition in java and pass byte array value in it. Providing some online reference is much appreciated.
C# Code
byte[] date = //file in byte format
var fileContent = new StreamContent(new MemoryStream(data));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"files\"",
FileName = "\"" + filename + "\""
}; // the extra quotes are key here
fileContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
var content = new MultipartFormDataContent();
content.Add(fileContent);
HttpResponseMessage response = null;
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, _url + uri);
request.Content = content;
My Java Code
StringBody name = new StringBody("\"files\"", ContentType.MULTIPART_FORM_DATA);
StringBody file = new StringBody("\"" + filename + "\"", ContentType.MULTIPART_FORM_DATA);
HttpEntity entity = MultipartEntityBuilder.create()
.addPart("Name", name)
.addPart("FileName", file)
.addBinaryBody("file", data)
.build();
Postmethod = new HttpPost(_url + uri);
Postmethod.addHeader(useragent);
Postmethod.addHeader(Accesstoken);
Postmethod.setEntity(entity);
Postmethod.addHeader("content-type", contentType);
response = httpClient.execute(Postmethod);
The response status code is 400 .Where did I go wrong?
Thanks in Advance..
I am trying to use the HttpClient library (in order to call the Facebook API's REST end points) to obtain a session key and verify user...
My code is here:
RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations =
{ "classpath*:**/*applicationContext-test.xml" })
public class FacebookUserTest
{
final String API_KEY = "9e2568d68f182a2957878f3acedd9453";
final String SECRET = "f1298956895d39110be92a672e0d2284";
final String TOKEN = "aa0c41aa4532053e8d0097844ab9bc7d";
final String LOGIN = "http://www.facebook.com/login.php";
final String HOST = "http://www.facebook.com/restserver.php";
private static Logger log =
LoggerFactory.getLogger(FacebookUserTest.class);
protected FacebookUser FacebookUser;
#Test
public void testFindUserBySessionKey() throws Exception
{
loginToFacebook();
String sessionKey = getSessionKey();
}
public void loginToFacebook() throws Exception
{
HttpClient client = new HttpClient();
client.setParams(new HttpClientParams());
client.setState(new HttpState());
GetMethod get = new GetMethod(LOGIN + "?api_key=" + API_KEY
+ "&v=1.0&auth_token=" + TOKEN);
// Get login screen
client.executeMethod(get);
// Post credentials to login
PostMethod post = new PostMethod(LOGIN);
post.addParameter(new NameValuePair("api_key", API_KEY));
post.addParameter(new NameValuePair("v", "1.0"));
post.addParameter(new NameValuePair("auth_token", TOKEN));
post.addParameter(new NameValuePair("email", "user#email.com"));
post.addParameter(new NameValuePair("pass", "password"));
client.executeMethod(post);
}
public String getSessionKey() throws Exception
{
HttpClient client = new HttpClient();
// Obtain session key
String host = "http://www.facebook.com/restserver.php";
String sessSecret = "false";
String toMd = "api_key=" + API_KEY + "auth_token=" + TOKEN
+ "format=xmlgenerate_session_secret=" + sessSecret
+ "method=facebook.auth.getSessionv=1.0" + SECRET;
String md5 = Md5Utils.MD5(toMd);
PostMethod post = new PostMethod(HOST);
NameValuePair[] data = {
new NameValuePair("api_key", API_KEY),
new NameValuePair("auth_token", TOKEN),
new NameValuePair("format", "xml"),
new NameValuePair("generate_session_secret", SECRET),
new NameValuePair("method", "auth.getSession"),
new NameValuePair("sig", md5), new NameValuePair("v", "1.0")
};
post.setRequestBody(data);
post.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
post.setRequestHeader("User-Agent",
"Facebook API PHP5 Client 1.1 (curl) 5");
// execute method and handle any error responses.
client.executeMethod(post);
StringBuilder sb = new StringBuilder();
byte[] b = new byte[4096];
for (int n; (n = post.getResponseBodyAsStream().read(b)) != -1;)
{
sb.append(new String(b, 0, n));
}
String sessionId = sb.toString();
log.warn("Session Id: " + sessionId);
return sessionId;
}
}
When I run my JUnit test, this is what is printed from the console:
WARN : com.myapp.FacebookUserTest - Session Id:
<?xml version="1.0" encoding="UTF-8"?>
<error_response xmlns="http://api.facebook.com/1.0/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://api.facebook.com/1.0/
http://api.facebook.com/1.0/facebook.xsd">
<error_code>104</error_code>
<error_msg>Incorrect signature</error_msg>
<request_args list="true">
<arg>
<key>api_key</key>
<value>9e2568d68f182a2957878f3acedd9453</value>
</arg>
<arg>
<key>auth_token</key>
<value>aa0c41aa4532053e8d0097844ab9bc7d</value>
</arg>
<arg>
<key>format</key>
<value>xml</value>
</arg>
<arg>
<key>generate_session_secret</key>
<value>f1298956895d39110be92a672e0d2284</value>
</arg>
<arg>
<key>method</key>
<value>auth.getSession</value>
</arg>
<arg>
<key>sig</key>
<value>fcf80d658f35d66396ac521da7102782</value>
</arg>
<arg>
<key>v</key>
<value>1.0</value>
</arg>
</request_args>
</error_response>
Could it be my MD5Utils code:
public class Md5Utils
{
private static String convertToHex(byte[] data)
{
StringBuffer buf = new StringBuffer();
for (int i = 0; i < data.length; i++) {
int halfbyte = (data[i] >>> 4) & 0x0F;
int two_halfs = 0;
do {
if ((0 <= halfbyte) && (halfbyte <= 9))
buf.append((char) ('0' + halfbyte));
else
buf.append((char) ('a' + (halfbyte - 10)));
halfbyte = data[i] & 0x0F;
}
while (two_halfs++ < 1);
}
return buf.toString();
}
public static String MD5(String text)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md;
md = MessageDigest.getInstance("MD5");
byte[] md5hash = new byte[32];
md.update(text.getBytes("iso-8859-1"), 0, text.length());
md5hash = md.digest();
return convertToHex(md5hash);
}
}
What am I possibly doing wrong to generate an incorrect signature?
Would really appreciate it if someone could help me or point me in the right direction...
Happy programming and thanks for reading!
Try this
string GenerateSignature(IDictionary<string, string> parameters)
{
StringBuilder signatureBuilder = new StringBuilder();
// Sort the keys of the method call in alphabetical order
List<string> keyList = ParameterDictionaryToList(parameters);
keyList.Sort();
// Append all the parameters to the signature input paramaters
foreach (string key in keyList)
signatureBuilder.Append(String.Format(CultureInfo.InvariantCulture, "{0}={1}", key, parameters[key]));
// Append the secret to the signature builder
signatureBuilder.Append(ConfigurationManager.AppSettings["FBApiSecret"]);
MD5 md5 = MD5.Create();
// Compute the MD5 hash of the signature builder
byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(signatureBuilder.ToString().Trim()));
// Reinitialize the signature builder to store the actual signature
signatureBuilder = new StringBuilder();
// Append the hash to the signature
foreach (byte hashByte in hash)
signatureBuilder.Append(hashByte.ToString("x2", CultureInfo.InvariantCulture));
return signatureBuilder.ToString();
}
string CreateHTTPParameterList(IDictionary<string, string> parameterList)
{
StringBuilder queryBuilder = new StringBuilder();
parameterList.Add("api_key", ConfigurationManager.AppSettings["FBApiKey"]);
parameterList.Add("v", "1.0");
parameterList.Add("call_id", DateTime.Now.Ticks.ToString("x", CultureInfo.InvariantCulture));
parameterList.Add("sig", GenerateSignature(parameterList));
//parameterList.Add("sig", _sig);
// Build the query
foreach (KeyValuePair<string, string> kvp in parameterList)
{
queryBuilder.Append(kvp.Key);
queryBuilder.Append("=");
queryBuilder.Append(HttpUtility.UrlEncode(kvp.Value));
queryBuilder.Append("&");
}
queryBuilder.Remove(queryBuilder.Length - 1, 1);
return queryBuilder.ToString();
}
Example usage :
Dictionary<string, string> parameterList = new Dictionary<string, string>();
parameterList.Add("auth_token", authCode);
parameterList.Add("format", "json");
parameterList.Add("method", "facebook.auth.getSession");
string req = CreateHTTPParameterList(parameterList);
I tryed to copy / paste these codes from my old project.
I hope it will be help to you.
you have an error in your parameter you send in generate_session_secret your secret code , it must be true or false
you set:
new NameValuePair("generate_session_secret", SECRET),
there are conflict in your parameter that u set in post and the signature