I've been given a chunk of code which describes an "algorithm" for token generation. This code is written in Java and works as is correctly. The given Java code must remain exactly as is, however, my requirement is to have the same "algorithm" used within a PHP application and I'm having a hard time retrieving the same result.
Java code:
public static void main(String[] args)
throws
UnsupportedEncodingException,
NoSuchAlgorithmException {
// Let's stick to a fixed date for this SO question
//DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmm");
//dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
//String date = dateFormat.format(new Date());
String date = "201603251605";
String name = "some_dummy_data_one";
String size = "some_dummy_data_two";
// MD5 'name'
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(name.getBytes());
byte[] md5name = md5.digest();
// What happens here is beyond me - How would one translate this to PHP?
byte[] sizeBytes = (size + date).getBytes();
byte[] tokenBytes = new byte[md5name.length + sizeBytes.length];
System.arraycopy(sizeBytes, 0, tokenBytes, 0, sizeBytes.length);
System.arraycopy(md5name, 0, tokenBytes, sizeBytes.length, md5name.length);
// SHA256
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
sha256.update(tokenBytes);
byte[] tokenHash = sha256.digest();
System.out.println(Base64.getEncoder().encodeToString(tokenHash));
}
This prints:
LsPw/5/4uKmQfVaU1LRASxG89mgMt7OxX+h7JGRo1ZU=
Ultimately and ideally I'd love a quick way to just get the same result with PHP code, but I've the urge to understand what's going on instead of just reaching the desired result.
Now to attempt to display that I have at least done a little homework and I'm not just seeking someone to do my work for me, up until the MD5 conversion of the strings, I've managed to get an identical base64 encoded SHA256 string of a single string skipping the middle chunk of code containing the 'System.arrayCopy' bit:
Java code:
public static void main(String[] args)
throws
UnsupportedEncodingException,
NoSuchAlgorithmException {
String date = "201603251605";
// MD5 'name'
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(date.getBytes());
byte[] md5Date = md5.digest();
// SHA256
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
sha256.update(md5Date);
byte[] tokenHash = sha256.digest();
System.out.println(Base64.getEncoder().encodeToString(tokenHash));
}
PHP code:
private function generateToken() {
$md5Date = md5("201603251605", true);
$shaString = hash("sha256", $md5Date, true);
return base64_encode($shaString);
}
Java output:
mEkkRlBkwyoWFMsA+v/hP/m9sD6FdzM6LZHIORtr260=
PHP output:
mEkkRlBkwyoWFMsA+v/hP/m9sD6FdzM6LZHIORtr260=
So according to the above, my md5 and sha of a single string works fine, but that's not the problem. The problem is understanding what is happening when multiple strings are defined and are being mashed together in the Java code. Why does it seem overly complicated and is there a simple way of doing it in PHP?
Could somebody please explain what is happening in between the MD5 and SHA256 generation so that I can translate it to PHP code? I've attempted to read up on the Java System.arrayCopy documentation, but I feel as though I'm not experienced/smart enough to understand what is going on there. If there's a simple solution to this, I'd appreciate it very much.