I am trying to integrate fireblock APIs in my application. I am always getting 401 unauthorized: invalid signature error. Attaching the code for reference. Please check and let me know if I am doing anything wrong here.
@Value("${fireblocks.api.key}")
private String apiKey;
@Value("${fireblocks.privateKey.path}")
private String privateKeyPath;
private static final String FIREBLOCKS_API_URL = "https://sandbox-api.fireblocks.io/v1";
public String generateJWT() throws Exception {
PrivateKey privateKey = getPrivateKey(privateKeyPath);
long nowMillis = System.currentTimeMillis();
long expMillis = nowMillis + 60000; // 1 minute expiration
Date now = new Date(nowMillis);
Date exp = new Date(expMillis);
String token = Jwts.builder()
.setIssuedAt(now)
.setExpiration(exp)
.setIssuer(apiKey)
.signWith(privateKey, SignatureAlgorithm.RS256)
.compact();
return token;
}
private static PrivateKey getPrivateKey(String privateKeyPath) throws Exception {
String privateKeyPEM = readPrivateKeyPEM(privateKeyPath);
byte[] privateKeyBytes = decodePEM(privateKeyPEM);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}
private static String readPrivateKeyPEM(String privateKeyPath) throws Exception {
try (FileReader reader = new FileReader(privateKeyPath)) {
StringBuilder sb = new StringBuilder();
int ch;
while ((ch = reader.read()) != -1) {
sb.append((char) ch);
}
return sb.toString();
}
}
private static byte[] decodePEM(String pem) {
// Strip out PEM header/footer and decode base64
String privateKeyPEM = pem
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s+", "");
return Base64.getDecoder().decode(privateKeyPEM);
}
public String callFireblocksApi(String jwtToken) throws IOException {
String url = FIREBLOCKS_API_URL + "/transactions"; // Adjust this endpoint as needed
Request request = new Request.Builder()
.url(url)
.addHeader("X-API-Key", apiKey)
.addHeader("Authorization", "Bearer " + generateJWT())
.build();
try (Response response = httpClient.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
return response.body().string();
}
}