Skip to content

Commit 0b5275f

Browse files
authored
Update signature authentication (#89)
* Add nonce to payload * Upgrade to Hashing to SHA-384 * Resolve * to single class imports * Satisfy linter on testcase docstring => added those checks to local environment also.
1 parent a516b00 commit 0b5275f

File tree

2 files changed

+40
-9
lines changed

2 files changed

+40
-9
lines changed

Diff for: src/main/java/com/transloadit/sdk/Request.java

+28-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
import org.joda.time.format.DateTimeFormatter;
1515
import org.json.JSONObject;
1616

17+
import javax.crypto.KeyGenerator;
1718
import javax.crypto.Mac;
19+
import javax.crypto.SecretKey;
1820
import javax.crypto.spec.SecretKeySpec;
1921
import java.io.File;
2022
import java.io.IOException;
@@ -26,6 +28,7 @@
2628
import java.security.InvalidKeyException;
2729
import java.security.NoSuchAlgorithmException;
2830
import java.util.ArrayList;
31+
import java.util.Base64;
2932
import java.util.HashMap;
3033
import java.util.Map;
3134
import java.util.Random;
@@ -303,6 +306,7 @@ private RequestBody getBody(Map<String, String> data, @Nullable Map<String, File
303306
private Map<String, String> toPayload(Map<String, Object> data) throws LocalOperationException {
304307
Map<String, Object> dataClone = new HashMap<String, Object>(data);
305308
dataClone.put("auth", getAuthData());
309+
dataClone.put("nonce", getNonce("AES", 256));
306310

307311
Map<String, String> payload = new HashMap<String, String>();
308312
payload.put("params", jsonifyData(dataClone));
@@ -350,14 +354,14 @@ private Map<String, String> getAuthData() {
350354
*/
351355
private String getSignature(String message) throws LocalOperationException {
352356
byte[] kSecret = transloadit.secret.getBytes(Charset.forName("UTF-8"));
353-
byte[] rawHmac = hmacSHA1(kSecret, message);
357+
byte[] rawHmac = hmacSHA384(kSecret, message);
354358
byte[] hexBytes = new Hex().encode(rawHmac);
355-
356-
return new String(hexBytes, Charset.forName("UTF-8"));
359+
String signature = "sha384:" + new String(hexBytes, Charset.forName("UTF-8"));
360+
return signature;
357361
}
358362

359-
private byte[] hmacSHA1(byte[] key, String data) throws LocalOperationException {
360-
final String algorithm = "HmacSHA1";
363+
private byte[] hmacSHA384(byte[] key, String data) throws LocalOperationException {
364+
final String algorithm = "HmacSHA384";
361365
Mac mac;
362366

363367
try {
@@ -371,6 +375,25 @@ private byte[] hmacSHA1(byte[] key, String data) throws LocalOperationException
371375
return mac.doFinal(data.getBytes(Charset.forName("UTF-8")));
372376
}
373377

378+
/**
379+
* Generates a strong cryptographic nonce in order to make the request's signature unique.
380+
* @param cipher Algorithm to derive key with
381+
* @param lengthInBits Length of the generated key in bits
382+
* @return A Key formatted as String
383+
*/
384+
protected String getNonce(String cipher, int lengthInBits) {
385+
KeyGenerator keyGenerator = null;
386+
try {
387+
keyGenerator = KeyGenerator.getInstance(cipher);
388+
} catch (NoSuchAlgorithmException e) {
389+
throw new RuntimeException(e);
390+
}
391+
keyGenerator.init(lengthInBits);
392+
SecretKey secKey = keyGenerator.generateKey();
393+
String encodedKey = Base64.getEncoder().encodeToString(secKey.getEncoded());
394+
return encodedKey;
395+
}
396+
374397
/**
375398
* Helper method, which performs a retryRateLimit action if a POST request has hit the servers rate limit.
376399
* All parameters of the failed POST request should be provided to this method.

Diff for: src/test/java/com/transloadit/sdk/RequestTest.java

+12-4
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,18 @@ public void retryAfterSpecificErrors() throws LocalOperationException, RequestEx
179179
testRequest.delete("/foo", new HashMap<String, Object>());
180180
}
181181

182+
/**
183+
* Test secure nonce generation with.
184+
*/
185+
@Test
186+
public void getNonce() {
187+
String cipher = "Blowfish";
188+
int keyLength = 256;
189+
190+
String nonce = request.getNonce(cipher, keyLength);
191+
assertEquals(44, nonce.length());
192+
}
193+
182194
/**
183195
* Tests if {@link Request#delayBeforeRetry()} works.
184196
* @throws LocalOperationException
@@ -194,8 +206,4 @@ public void delayBeforeRetry() throws LocalOperationException {
194206
assertTrue(delta >= timeout);
195207

196208
}
197-
198-
199-
200209
}
201-

0 commit comments

Comments
 (0)