# Is it safe to hash a packet with a shared secret to prove authenticity?

I am developing an online game, where the server is written in Node.js and the client uses Godot. The issue is that Godot has no cryptographic functionalities (it can only encrypt and decrypt files, not elements in memory).

As implementing cryptographic functionality would be out of my capabilities with Godot, I've been thinking of a way to authenticate UDP packets.

I have the following idea: client logs in via HTTPS and gets a refresh token, and a shared (with the server) secret. The refresh token is used to renew the secret every 10 mins.

To authenticate UDP packets (which are sent unencrypted), the packet contents are hashed with the secret included, the packet is sent with the hash. Then the other side verifies that the hash with the secret is valid.

Is this approach secure enough? Considering that the secrets would be randomly generated long strings, would an attacker be able to calculate the secret by analizing several packets? My options for hashing are MD5 and SHA256 which are the algorithms available in Godot.

Being that UDP is only used for game events which don't need extreme security (so no personal information, payment details etc are ever sent in this channel), would this work?

• Beware replayed packets if you don't have a message sequence number involved that the recipient verifies. – Squeamish Ossifrage Jun 11 '18 at 17:47

## 1 Answer

From what you I described I understand your scheme to be following: Each message $M$ gets a tag $T$ which is $H(S \mathbin\| M)$ where $H$ can be MD5 or SHA2 and $S$ is a common secret. Both hash functions are vulnerable to a length-extension attack effectively allowing to compute $H(S\mathbin\|M\mathbin\|x)$ from $H(S\mathbin\|M)$ and the length of $M$ so your scheme should not be used for authentication.

A better alternative would be to use a message authentication code (short MAC), which is a group of algorithms specifically crafted for cases similar to yours, including the widespread HMAC which allows to turn even broken hash-algorithms like MD5 into relatively secure MAC's.

• One may want to note that an implementation of HMAC isn't all that hard and you don't actually need the specific HMAC constants for the security reduction to work, the inner and the outer key just need to be different somehow. – SEJPM Jun 11 '18 at 17:27
• I suggest you stick to ordinary HMAC without tweaks. If you can't compute $k \oplus \mathrm{0x5c5c\cdots5c}$ and $k \oplus \mathrm{0x3636\cdots36}$, there's probably something very wrong with Godot! If you use standard HMAC, beyond making the code easier to audit without raising eyebrows, the protocol is easy to interoperate with in any system that does have built-in HMAC logic. – Squeamish Ossifrage Jun 11 '18 at 17:42
• Thanks, I read up on HMAC and does indeed seem rather easy to implement. Is there a similar method for signing packets where the clients don't know the secret (similar to public/private key encryption)? – Reethok Jun 11 '18 at 18:01
• When it comes to asymetric signing, the most commonly used algorithms are RSA and ECDSA, however, both tend to be a lot slower and much easier to do wrong / having side-channels, so you really shouldn't implement them yourself. And since it seems like your application requires speed, the better solution may be to use (Elliptic-Curve-)Diffie-Hellman to exchange ephemeral keys. – VincBreaker Jun 11 '18 at 18:35