Пытаюсь получить данные методом getInfo вот из этого API https://yobit.net/ru/api/
Каждый запрос должен пройти аутентификацию. Аутентификация происходит способом отправки следующих HTTP-заголовков:
Key - API-ключ, пример: FAF816D16FFDFBD1D46EEF5D5B10D8A2
Sign - цифровая подпись, POST-параметры (?param0=val0 & ...& nonce=1) подписанные секретным ключом с помощью HMAC-SHA512
Для Http запроса использую ApacheHttp.
Метод Post - запроса
public static String postApache(String url) {
String dataFormServer = "";
String dataToServer="?method=getInfo&nonce=20";
String key = "xxx";
String secretKey = "yyy";
String signedData = calculateHMAC(dataToServer, secretKey);
try {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> params = new ArrayList<NameValuePair>(2);
params.add(new BasicNameValuePair("Key", key));
params.add(new BasicNameValuePair("Sign",signedData));
httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
CloseableHttpResponse response = client.execute(httpPost);
HttpEntity entity = response.getEntity();
if (entity != null) {
dataFormServer = org.apache.commons.io.IOUtils.toString(entity.getContent(), "cp1251");
}
else System.out.println("Error");
} catch (IOException e) {
e.printStackTrace();
}
return dataFormServer;
}
HMAC генератор
private static String calculateHMAC(String data, String key) {
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), HMAC_SHA512);
Mac mac = null;
try {
mac = Mac.getInstance(HMAC_SHA512);
mac.init(secretKeySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return toHexString(mac.doFinal(data.getBytes()));
}
private static String toHexString(byte[] bytes) {
final char[] hexArray = "0123456789ABCDEF".toCharArray();
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
Сервер отвечает {"success":0,"error":"invalid key, sign, method or nonce"}
Ошибка может быть как в HMAC генераторе, так и в методе postApache. Не уверен ни в том ни в том.
В документации написано, что Key / Sign
это заголовки, а вы отправляете их как POST-данные. ?method=getInfo&nonce=20
вот это вы вообще не отправляете нигде. В меня сработал такой код:
public static String postApache(String url) {
String dataFormServer = "";
String dataToServer = "method=getInfo&nonce=7";
String key = "---";
String secretKey = "---";
String signedData = calculateHMAC(dataToServer, secretKey);
try {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Key", key);
httpPost.addHeader("Sign", signedData);
httpPost.setEntity(new ByteArrayEntity(dataToServer.getBytes(), ContentType.APPLICATION_FORM_URLENCODED));
CloseableHttpResponse response = client.execute(httpPost);
HttpEntity entity = response.getEntity();
if (entity != null) {
dataFormServer = IOUtils.toString(entity.getContent(), StandardCharsets.UTF_8);
}
else System.out.println("Error");
} catch (IOException e) {
e.printStackTrace();
}
return dataFormServer;
}
private static String calculateHMAC(String data, String key) throws DecoderException {
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "HMACSHA512");
Mac mac = null;
try {
mac = Mac.getInstance("HMACSHA512");
mac.init(secretKeySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
byte[] hmac = mac.doFinal(data.getBytes());
return Hex.encodeHexString(hmac);
}
Решил проблему, может кому пригодится. Использовал бибилотеку commons-codec. Вот рабочий метод кодирования в sha512
private static String calculateHMAC(String data, String key) {
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), HMAC_SHA512);
Mac mac = null;
try {
mac = Mac.getInstance(HMAC_SHA512);
mac.init(secretKeySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
try {
return Hex.encodeHexString(mac.doFinal(data.getBytes("UTF-8")));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
Тут смесь стандартной библиотеки java javax.crypto и апачевской commons-codec. Можно переписать на чистом Apache, получится меньше кода, но не стал заморачиваться.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
ЗдравствуйтеУстановил идею и возникла проблема не могу создать класс никакой - выходит сообщение -
Мне нужно узнать, сколько байт в оперативной памяти занимает определенная коллекция в моем приложении (ArrayList)Нужно это для того, чтобы представлять,...
Добрый день! Написал тут программу, которая должна считать кол-во дней до какой-то датыСтолкнулся с тем, что не совсем корректно работают...
Задача: Сделать 3 потока, которые будут выполнятся друг за другом, то есть 2-ой поток идет за 1-ым, а 3-ий за вторым, 1-ый за 3-имЗадача должна быть...