Mike Gwilt
Mike Gwilt

Reputation: 2449

What is the .NET Equivalent of Java's SecretKeySpec class?

I was provided the following code sample in Java and I'm having trouble converting it to C#. How would I go about converting this so it'll work in .NET 4.5?

public static String constructOTP(final Long counter, final String key) 
    throws NoSuchAlgorithmException, DecoderException, InvalidKeyException 
{ 
    // setup the HMAC algorithm, setting the key to use         
    final Mac mac = Mac.getInstance("HmacSHA512");                  

    // convert the key from a hex string to a byte array         
    final byte[] binaryKey = Hex.decodeHex(key.toCharArray());                  

    // initialize the HMAC with a key spec created from the key         
    mac.init(new SecretKeySpec(binaryKey, "HmacSHA512"));  

    // compute the OTP using the bytes of the counter         
    byte[] computedOtp = mac.doFinal(                 
    ByteBuffer.allocate(8).putLong(counter).array());  

    //         
    // increment the counter and store the new value         
    //                  

    // return the value as a hex encoded string         
    return new String(Hex.encodeHex(computedOtp));     
} 

Here is the C# code that I've come up with thanks to Duncan pointing out the HMACSHA512 class, but I'm unable to verify the results match without installing java, which I can't do on this machine. Does this code match the above Java?

    public string ConstructOTP(long counter, string key)
    {
        var mac = new HMACSHA512(ConvertHexStringToByteArray(key));
        var buffer = BitConverter.GetBytes(counter);

        Array.Resize(ref buffer, 8);

        var computedOtp = mac.ComputeHash(buffer);

        var hex = new StringBuilder(computedOtp.Length * 2);

        foreach (var b in computedOtp)
            hex.AppendFormat("{0:x2", b);

        return hex.ToString();
    }

Upvotes: 1

Views: 4118

Answers (1)

Duncan Jones
Duncan Jones

Reputation: 69389

A SecretKeySpec is used to convert binary input into something that is recognised by Java security providers as a key. It does little more than decorate the bytes with a little post-it note saying "Pssst, it's an HmacSHA512 key...".

You can basically ignore it as a Java-ism. For your .NET code, you just need to find a way of declaring what the HMAC key is. Looking at the HMACSHA512 class, this seems quite straight-forward. There is a constructor that takes a byte array containing your key value.

Upvotes: 2

Related Questions