Converting HMAC-SHA1 from node.js to Java
<p>I have been tasked with converting some existing piece of node.js code to Java. I think I'm well on my way, but I'm kind of stuck right now. The output of the methods do not seem to match.</p>

<p>What I'm doing is creating a SHA-1 signature based on a query string. This query string contains some query-related data (not relevant for this question) and an API key.</p>

<p><strong>Important</strong></p>

<ul>
<li>The <code>api_secret</code> string in node.js is equivalent to <code>Config.API_SECRET</code> in Java.</li>
<li>Example query string (these are equal in the node.js and Java program):<br>
<code>/events?festival=imaginate&amp;pretty=1&amp;size=100&amp;from=0&amp;key=SOME_KEY</code></li>
</ul>

<p><strong>Actual code</strong></p>

<p>The SHA-1 hmac is initialized as follows in nodejs:</p>

<pre><code>const hmac = crypto.createHmac('sha1', api_secret);
</code></pre>

<p>The SHA-1 mac is initialized as follows in Java:</p>

<pre><code>final SecretKeySpec secretKeySpec = new SecretKeySpec(Config.API_SECRET.getBytes("UTF-8"), "HmacSHA1");
final Mac hmac = Mac.getInstance("HmacSHA1");
hmac.init(secretKeySpec);
</code></pre>

<p>Next, the node.js program updates the hmac as such (<code>query</code> parameter is as listed above):</p>

<pre><code>hmac.update(query, 'ascii');
</code></pre>

<p>Which I replicated in Java like this (<code>query</code> parameter is equal to the node.js <code>query</code> parameter):</p>

<pre><code>hmac.update(query.getBytes("US-ASCII"));
</code></pre>

<p>Finally, the byte string is converted to a SHA-1 hash as such in the node.js program:</p>

<pre><code>const signature = hmac.digest('hex');
</code></pre>

<p>I couldn't find an exact translation to Java, but this was my attempt, which I think does about the same thing:</p>

<p><em>Byte array to hex function</em></p>

<pre><code>public static String byteArrayToHex(byte[] a) {
    StringBuilder sb = new StringBuilder(a.length * 2);
    for(byte b: a)
        sb.append(String.format("%02x", b &amp; 0xff));
    return sb.toString();
}
</code></pre>

<p><em>Actual usage</em></p>

<pre><code>byte[] result = hmac.doFinal();
MessageDigest md = MessageDigest.getInstance("SHA-1");
String sha1Hash = byteArrayToHex(md.digest(result));
</code></pre>

<p>However, this is where I get confused. The node.js program returns this hash:
<code>18cf4fce7bd6163c64d3b2ea8d935b0f16720fe3</code></p>

<p>But my Java program gives this hash as output:
<code>f65f8738cce89134dc73709e3353d94c83ccf1fb</code></p>

<p>I can't figure out where I went wrong and I really hope someone could shed a light on this.</p>