I'm working with a payment provider which uses the following algorithm for signing messages:
- The merchant is securely given a secret key
k, known to them and the payment provider only. EDIT: Usually the key is quite long. The payment is implemented by using a redirect, and the merchant later receives callbacks containing information about the success or failure of the payment operation. The merchant considers this information trustworthy. Here is an example of a successful payment callback for order no. 1234 and a merchant hosted at
example.com:example.com?orderID=1234&paymentStatus=SUCCESS&...&signature=abcdThe message
mwhich is signed is formed in the following way:orderid=<..>|paymentStatus=<..>|...The signature algorithm
S(m,k)is chosen to be:signature=H(m||k)(m||kmeansmconcatenated with the secret keyk) whereHis a hashing function, in this caseMD5.- The verification algorithm is
V(signature, m, k)and returns true only ifH(m||k) = signature.
As far as I understood the inner workings of MD5 if the signing algorithm was S(m,k) = H(k||m) then this would be totally insecure because if an attacker knows H(k||m) she may be able to calculate H(k||m||m') where m' is a message of her choice - this would mean that the signature is vulnerable to both existential and selective forgery. Correct? But deliberately or not the algorithm is S(m,k) = H(m||k) - the key is put last in the concatenated string.
So far I cannot think of exploitable vulnerability in this protocol (I'm not considering the problems inherent to MD5). Any ideas, is this secure enough?