-
Hello, it's not really a bug because it seems to work in this implementation but I'm trying to transcribe librespot in C# and I encounter a problem. During the initial request to retrieve the client token, a challenge is asked which doesn't seem to happen in librespot-java.
Librespot doesn't seem to solve these challenges in the ApiClient class, if anyone could enlighten me on this point. Also, during the HashCash challenge in this request there is no LoginContext and the length is not the same (20) so the resolution algorithm must be somewhat different. |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 11 replies
-
@devgianlu Thanks for the move on the right place. As you have implemented the new playplay HTTP API, don't have you encountered these challenges ? |
Beta Was this translation helpful? Give feedback.
-
The playplay request isn't implemented yet as there are some fields missing that I don't know how to retrieve. I have implemented the clienttoken request, but didn't encounter any challenge, probably because the device id is already marked as logged in and therefore a challenge has already been resolved. |
Beta Was this translation helpful? Give feedback.
-
Just use SHA1("")[12:20] as uint64 (BigEndian). |
Beta Was this translation helpful? Give feedback.
-
Hey, i'm trying to solve the hashcash challenge that happens during the connection to the accesspoint I've tried to solve this challenge with the algorithm mentionned in this thread and with the one implemented in librespot-java but i couldn't get the expected result. Could someone point me in the right direction for this pelase ? By the way here's the current algo i'm testing : import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.nio.ByteBuffer;
import java.math.BigInteger;
public class Main {
public static void main(String[] args) throws NoSuchAlgorithmException {
String prefix = "9c89f21fe8b7031aea17767de5aebe55";
int length = 14;
byte[] seed = new byte[8];
byte[] target = bigIntToByteArray(1852);
System.out.println(bytesToHex(target));
System.arraycopy(target, 0, seed, 0, 2);
byte[] new_prefix = hexStringToByteArray(prefix);
solveHashCash(new_prefix, length, seed);
// Expected : 5a352d14c2c6c664000000000000e079
}
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
private static byte[] bigIntToByteArray(final int i) {
BigInteger bigInt = BigInteger.valueOf(i);
return bigInt.toByteArray();
}
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
private static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
}
return data;
}
private static void incrementCtr(byte[] ctr, int index) {
ctr[index]++;
if (ctr[index] == 0 && index != 0)
incrementCtr(ctr, index - 1);
}
private static void solveHashCash(byte[] prefix, int length, byte[] random) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA1");
byte[] suffix = new byte[16];
System.arraycopy(random, 0, suffix, 0, 8);
while (true) {
md.reset();
md.update(prefix);
md.update(suffix);
byte[] digest = md.digest();
ByteBuffer buf = ByteBuffer.wrap(digest);
Long bufLong = buf.getLong(12); // [12:20]
if (Long.numberOfTrailingZeros(bufLong) >= length) { // CTZ
System.out.println("Output: " + bytesToHex(suffix));
return;
}
incrementCtr(suffix, suffix.length - 1);
incrementCtr(suffix, 7);
}
}
}``` |
Beta Was this translation helpful? Give feedback.
Just use SHA1("")[12:20] as uint64 (BigEndian).