One of the payment solutions for the websites provides the following way of creating security hash for payment link:

hash = sha1(private_key + payment_params_json + private_key);

Is there any particular reason for using the same private_key twice?

  • 3
    This is a crude attempt at constructing an HMAC. I would hesitate to use such a payment system; if this is the quality of the cryptography they display publicly, the quality they use internally is certainly worse. – Stephen Touset Apr 7 '15 at 17:10

This construct can (crudely) protect against a length extension attack, which in particular affects hashes built using the Merkle-Damgård construction (such as MD5, SHA-1, and the SHA-2 family).

The gist of the attack is that an attacker who knows H(s || m) and m for a hash H, secret s, and message m can trivially forge a hash of the form H(s || m || p || a) where p is the internal padding used by the hash function and a is an attacker-controlled string. This may seem difficult to exploit in practice, as p is typically raw bytes such as \x04\x04\x04\x04. However, consider a message such as a set of HTTP query parameters: username=x&admin=false. With this attack, you can forge a "signed" message for username=x&admin=false\x02\x02&admin=true. Depending on how the parameters are parsed, the URL parser could easily use the latter value of admin rather than the former.

Hashing the secret at the end of the message is, presumably, an attempt to defend against this type of attack. Since the attacker doesn't know the secret, they can't use a length extension attack since they have no way of forging H(s || m || p || a || s) without knowing s.

That said, there are existing cryptographic constructs that are proven secure for use as message authentication codes. In this case, HMAC is probably the cryptographic primitive they want to use, as it has a strong proof of security.

This type of home-grown construct is evidence that the authors of this service are not well-versed in cryptography. If they were, an HMAC would be a natural and obvious choice for such a situation. If they are comfortable publishing these kinds of embarrassing home-grown constructs in their public documentation, I would personally worry about the cryptography they deploy and use internally.


I am going to base my answer on a couple of assumptions as below.

  • The secret key is randomly generated or not easily guessable
  • The secret key is just that, a secret.

Using two private keys in this instance has no viable benefits to security, presuming that the key was never accessed by a third party (So you are looking at reverse cryptographic attacks).

However, if the need is derived with the thought of A third party potentially accessing one key, then if both of the private keys were stored in separate locations not accessible directly outside of the application (E.G API/DB based) then perhaps it would add another layer of security if the worst was to happen.

  • 2
    Is it two private keys? My reading of the question was that it was the same private key, used twice. – TRiG Apr 7 '15 at 10:40
  • 1
    Thank you for the answer. I should have mentioned that there are no two different private keys, but just one, which is simply repeated two times. I should edit my question – Oleg Apr 7 '15 at 10:40
  • 2
    This is not strictly true. This construct (crudely) guards against length extension attacks, where an attacker knowing H(m) but not m can generate H(m+p+a) where p is the padding used by the hash function and a is attacker-controlled. Since the attacker doesn't know the secret key being used, he can't ensure his message ends with it. The real solution to this is to use the correct cryptographic construct: a MAC. More specifically, they probably want an HMAC. – Stephen Touset Apr 7 '15 at 17:06
  • @StephenTouset, you ought to turn your comments (here and on the question) into an answer. – Jander Apr 7 '15 at 20:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.