last day (16 days later) » 

11:43 AM
0
Q: Using HMAC when sending data through an untrusted server

PaulI have a set up like this: Payment Server (PS) <> Front End (FE) <> Client JS. I need to get some data from the Client JS to the PS, without the FE being able to modify it and have PS prove that correct. In this situation, the FE acts as store and forward (with some basic validation of the paylo...

 
atk
Why are you using hmac instead of digital signatures?
 
@atk Would you mind elaborating? AFAIK, digital signatures requires a certificate and that's not an option. Isn't the process pretty similar, but encrypts the data too? If so, that isn't an option as I would still like the FE to do some basic validation of the data before passing through.
Edited question to show preferable to see data and not have it encrypted.
 
atk
that still doesn't answer why you chose an hmac/shared key over a digital signature (private key).
 
@atk I am happy to use digital signatures if that is an option, but doesn't it need a certificate? Wouldn't it make it more complicated than using a PIN? I didn't 'choose' hmac, it was the only way I know.
 
atk
Yes, it needs a certificate, but you can generate certificates with or without an external certificate authority. It will be substantially stronger than a PIN and will not suffer from transmitting a secret key around (or weak PIN based key generation).
Actually, correction: it needs a private/public key pair that you trust, which is most commonly accomplished with a certificate. You can establish trust another way if you absolutely have to.
 
11:43 AM
I see, I don't think that would be suitable for the pop up then as the user isn't going to use the same machine, browser etc each time and I can't see that the user would move it from place to place. However, that sounds like it would be great for a Android/ios app. Thank you.
 
atk
You still have to share the secret key every time... what are you trying to protect against with your hmac scheme that wouldn't be better implemented by just using tls?
 
Our payment service is very isolated, it has just one external facing access (to talk to currency networks) and one internal facing access (our API). Our front end is where we deal with the user, creating transactions and approving them etc.We have designed the API to not trust the front end, so once a user has been configured, - even if the front end was completely replaced, the API would not
allow the payment to happen. The general idea is that the Payment Service will trust that the API call is from the user and not from someone who is intercepting our front end somehow. The user to FE is tls and from FE to API is tls.
By using a PIN that only the API knows, alongside the authy token (that is included in the hmac generation), I think the API will be able to prove that the message comes from the correct user and has not been tampered with by the FE (e.g. changed the payment address).
 
12:18 PM
The only time the secret PIN is sent, is when initially set (or when changing the PIN). The JS will take the users PIN, covert it to the hash and then use that to create the hmac. The PIN itself is not sent with these transactions and is only ever in the users browser.
 
 
9 hours later…
atk
9:14 PM
If you're trying to deal with the case of a compromised front end, then you need something whose trust doesn't depend upon the front end being secure. The PIN is known to the front end, and so is its hash, so the PIN can't solve this for you (if I understand your need, correctly).
PINs are usually very weak, as well. This makes them highly guessable.
There are other solutions that do work like this, though, and are much stringer than a PIN.
The first example is digital signatures/certificates. They don't work in your case, but when they are appropriate, they are very effective. The front end can't mess with the request because it doesn't know the user's private key. You also get nonrepudiation, so the user cannot claim that they did not initiate a transaction (unless their private key was compromised)
Contrast that to the hmac where the fe knows the pin. The fe can just create a new message and generate its own hmac. Or, because the pin is likely weak, after a few (thousand) tries, the attacker can guess the pin and generate their own hmac.
The cert would have to be issued/signed outside the app though. If the fe has the ability to generate or replace the cert, you lose protection from the compromised fe.
 
atk
But certs aren't right for you right now. I described them a little in case you go that way, later :-) you need an alternative solution. Thinking about oob uthn (like google's OTP via SMS), it might work.
In oob, you basically receive transaction details via the fe, then send those details along with a a pin or other similar system to the user via sms or email, etc.
If the user accepts the transaction, s/he enters the pin into the app, or sends an sms back to the sending service, and approves the transaction. The fe can't fake things because the user gets informed about the transaction via another component (the fe does not send the sms, something else does). The fe cannot deliver the approval code, because it does not know the code.
The fe must not have read access to wherever the code is stored -another process must do the validation step.
 
atk
9:32 PM
Oh -and the approval code must be associated with the transaction, else the fe could create two transactions, one real and one fake, and use the approval code for the approved transaction on the unapproved transaction.
 
atk
There are variants of this, like hardware or software tokens (like securid)
--
You could also just create a secure tunnel directly from the client to the be. Not a network tunnel, but a logical tunnel. Have the server provide a second encryption key. The fe delivers this key to the client as part of the transaction. The client encrypts to this key. The fe has no access to the private key, and so cannot read the data. Client can send a randomly generated hmac key protected by the be public key, and hmac the transaction (now hmac is useful and based on a strong key).
BE is the only one that can read the data and can validate the transaction because of the hmac. Still doesn't give you nonrepudiation, but partially protects you from the fe. There is still the risk of the fe replacing the key when it is sent to the client. The client trusts the fe, and has no way to know if the key came from the be or not. The fe could replace the key with its own
And play man in the middle - reading and changning anything it wants.
So you're back to relying on some secret shared out of band.
 

  last day (16 days later) »