Consider the following requirement:

Bob should be able to verify that a payment request came from Alice.

The above is in simple terms the basic idea, however, in reality Alice would be user A of company XYZ and Bob would be a registered vendor for company XYZ.

My thinking on this was for each company that registers would have their own digital certificate (whether this be purchased by them or purchased by me on behalf of them if possible). When vendors are registered for that company they would be given access to the public key. When users authorise payments on behalf of that company a digital signature would be generated (perhaps using their user ID/email address) and sent along with the request. The vendor would then use the public key to verify that the request came from someone at company XYZ in order to process the payment.

I know the signature would no doubt need to be a bit more complex than just a user ID/email to avoid things like replay attacks/spoofing etc however, at a basic level does this seem the right approach?

I am fairly new to digital certs/signatures to any advice in general would be great.

migrated from stackoverflow.com Jun 6 '12 at 12:36

This question came from our site for professional and enthusiast programmers.

  • Should Bob be able to prove to Carol that the payment request came from Alice? – CodesInChaos Jun 7 '12 at 12:27
  • @CodeInChaos Yes Bob should be able to prove who the payment request came from Alice and that Alice works for Company XYZ. – James Jun 7 '12 at 13:30

Your thoughts go into the right direction in my opinion, although I hope I can convince you in the following to take a slightly different route.

Let's analyze your requirements:

  • You want to guarantee mutually authenticated requests for payment processing, i.e. a client initiating such a process would want to be sure of talking to the right server, and a server accepting a request would like to be sure of the identity of the peer. So the solution has to have server authentication plus client authentication

  • Integrity of the requests is another must - nobody should have the chance to alter anything in the request while it is on its way

These were the major requirements you listed. I would also add privacy to the mix - you possibly don't want anyone listening in on the traffic to be able to learn what the client purchased or the amounts of money they pay.

And now comes the tricky part. You can indeed achieve these goals with a mix of asymmetric and symmetric cryptography. But I think a manual scheme is not appropriate here, and here's the reasons why:

  • You are trying to secure the transport and the protection is ephemeral - once the transaction is done, you need no longer persist the request data (unless you try establishing an audit trail)

  • By securing the transport, you are actually designing a security protocol here. And getting them right is probably one of the hardest problems in cryptography. If you read about the Needham-Schroeder protocol: they were dead serious about this protocol for a couple of years, convinced that it was perfectly fine. And they had every right to do so, being decorated cryptographers and all. But three years later they were presented with a valid attack... you probably know where I'm heading and you yourself already mentioned the various things you would have to care about when trying to make this thing secure...

But not all is lost, because there's a perfectly fine protocol already doing all of the above and much more for you. It's TLS! It supports all of your requirements and has been tested by millions, so chances are overwhelming that your manual solution won't be able to compete with it anyway. And on the bright side, it's also already supported in all popular programming languages, no need for you to invent anything.

PS: When to use signatures vs. when to use TLS: it has always helped me to analyze my situation asking me this question: "Do you want to secure the transport?" vs. "Do you want to secure the data/document?"

  • So what your essentially saying is as long as I am using TLS/SSL for the communication between Client & Server there should be no need for digital signatures? – James Jun 5 '12 at 13:21
  • @James: You would use mutually authenticated TLS, which still requires certificates/keys for both the client and server, as in your originally planned scheme. But with that provided, it will do all the (a)symmetric crypto for you and you can be sure that it's secure. – emboss Jun 5 '12 at 13:25
  • Correct me if I am wrong here, but does that mean that the authentication is more tied to the machine rather than the user? Say I wanted to enable this from multiple devices how would it work in that scenario? Would each device looking to establish a connection to the server require a new certificate? – James Jun 5 '12 at 13:41
  • That entirely depends on what you want the entity impersonating the client certificate to represent. On the server side, the certificate is tightly bound to the particular server it runs on, due to hostname validation and all. But the situation is more relaxed on the client. There are basically no real naming restrictions. So if you want multiple client devices to represent the same entity, that's entirely possible - just let them share the same key/certificate. If you need to able to distinguish each device, then you would issue a distinct certificate to each, but it's not mandatory. – emboss Jun 5 '12 at 14:35
  • Just to make sure I understand you, say I had an app on a mobile device which would allow the users to authorise the payments. Each user would have to download their companies certificate to their device. When they authorise a payment, a TLS session would be established between their device & the server using the server certificate (mines) & their certificate (their companies) to send the payment request. Once received, the server would notify the vendor who would have to establish TLS session with their own certificate to pull down the data. Does that sound about right? – James Jun 6 '12 at 7:53

What you are trying to achieve is called non-repudiation (See http://en.wikipedia.org/wiki/Non-repudiation).

Signing with a certificate private key will provide a source for non-repudiation. Digital signing is normally considered personal so I would recommend that each individual has a separate certificate for digital signing. This also removes any confusion about who signed the request as each person can only sign for themselves. Signing certificates can be generated from an internal Certificate Authority (CA) where the system lives or provided by the user from an external issuing authority.

In summary:

Bob knows that Alice sent the payment request. Alice cannot deny she sent the payment request.

This is because:

  • Alice sent the payment request which is hashed (to protect against tampering) and then the hash is encrypted with Alice’s private key, creating a signature of the original request. The request would contain Alice’s details or user ID in the system. The hash and signing just makes sure it isn’t altered in any way.

  • Bob has Alice’s public key (which would likely be stored in the system) so he can hash the original request and decrypt request signature. This allows Bob to know that the request was sent by Alice by comparing the two hashes (because her name is in the request and her public key decrypted the hash) and the request has not been altered.

  • Bob can compare the certificate fields to determine that Alice is from the company she says she is.

See here for a visual reference: http://en.wikipedia.org/wiki/File:Digital_Signature_diagram.svg


  • This does not ensure that only Bob and Alice can read the request, that would be encryption (either message or transport).
  • Signing with a certificate private key ensures that message is not tampered with.
  • Metadata in the request/message will identify that Alice sent the request.

Also, if issuing from an internal CA you could also extend the certificate attributes to include a delegation limit which is often important in financial matter. i.e. The certificate says Alice can only order $30,000 or below.

  • This seems more along the lines of what I was thinking. However, I guess the problem is the cost of having a certificate per every user as opposed to a certificate per company. Couldn't I achieve the same goal by only having a company certificate which would be used to sign any user requests & include the user metadata as part of the requst? That means "Bob" would be able to verify the request came from Alice (metadata) who works for Company XYZ (public key). Also when you say "internal CA", do you mean if I was generating the certificates myself? – James Jun 7 '12 at 11:02
  • You could have a single certificate per company but it starts to blur the lines on who signed what. If that is not an issue then it might be ok. Yes, you can generate and issue certificates to customers or people using the order system/process. This can be done by using something like "Active Directory Certificate Services" which is normally free for enterprise Windows users, or OpenSSL for other platforms. – Bernie White Jun 7 '12 at 11:17
  • Ok so as part of setting up a new user on the system, I would not only add them to the DB, but I would generate a cert for them as well. The benefit of this (like you say) is I can set specific attributes like "Alice can only authorise payments up to £X amount." So if I wanted to change any attributes in the cert would I simply delete/regenerate or would I need to expire the old cert? How would that work as well if the cert is distrubuted to multiple devices? – James Jun 7 '12 at 11:53
  • I guess the part I am still unsure about is where the actual cert verification happens. Does the server verify the request from Alice before notifying Bob? Does the server simply store the request from Alice & notify Bob to pull down it down and have all the verification on the client-side? Does TLS simply do all this for me? – James Jun 7 '12 at 12:18

Your Answer

