2

I've implemented a licensing client and server for our web-applications. Currently there is only one way for licensing an app, user should manually upload the license file using specified form and menu in the management section.

I have four ways to publish the associated public key that is required to ensure license file's integrity:

  1. Using a key server. Application downloads the public key from the server. This is not always possible, some of our customers have restricted internet access for their servers.

  2. Hard-coding the public key. The easiest approach, but if we end up using several keys, we're going to have several different builds! And it'd be very painful to change the key afterwards.

  3. Ship it as a file beside web-application's files. This way it's easier to change and replace the file.

  4. Appending the public key inside the license file. This method seems very flexible and it's the best way that I came up with so far.

I'll be grateful to know your recommendations and whether it's secure to publish the public key with each license file, or not.

Philipp
  • 48,867
  • 8
  • 127
  • 157
Akbari
  • 145
  • 1
  • 6
  • 3
    How does this ensure the license file integrity? I think there is something I'm missing here. In general though, a public key can be distributed to anyone - that's kind of the point. – Matthew Jan 27 '16 at 14:05
  • The license file is signed with the private key, the information inside the file is plain text in XML, I use the public key to ensure its integrity... . So you think it's OK to distribute the public key with the license file? – Akbari Jan 27 '16 at 14:07
  • 1
    Ah, you're signing with the key. Yes, in that case, the public key can be public knowledge. No-one else can sign licence information with the private key, as long as you keep that secret, therefore the signed data is validated. – Matthew Jan 27 '16 at 14:09

5 Answers5

4

No.

You want to ensure license file's integrity by using a public key to verify. However, if you let your app receive the public key with the license file, an attacker ( who want to change the license file ) could just change the content, generate a new key to sign the content and replace your key with their key.

And your app will use attacker's public key to verify the signature, which is made by the attacker.

maowtm
  • 170
  • 1
  • 4
  • This exact thought made me write this question, is this really a risk in real world? What kind of distribution do you suggest? Thanks for your comment. – Akbari Jan 27 '16 at 18:10
  • 1
    @Akbari "is this really a risk in real world?" -- any attacker worth his salt will be able to spoof this. Either you are worried about attacks, in which case you should do security properly; or you're not, in which case why are you doing security at all? Providing knowingly broken security doesn't benefit anybody. – Mike Ounsworth Jan 29 '16 at 14:59
  • I will post a seperate answer to "What kind of distribution do you suggest?" – Mike Ounsworth Jan 29 '16 at 15:02
2

See comments - the licence information is signed with the private key, and validated using the public key.

In this case, the public key can be 100% public - no-one else should be able to sign data with the private key (as long as that is kept secret), and there is no (known) way to get back to the private key from a public key.

Publish it on your website, include it in the package, print it on the back of your stationary - all fine!

Just don't do the same with the private key. That should be kept under lock and key, ideally in a HSM.

Matthew
  • 27,233
  • 7
  • 87
  • 101
2

You need a trust anchor. In x509 PKI systems (used for TLS, S/MIME email, and code signing, among others), the trust anchor is provided by public certificate authorities.

Your public key (your certificate) is signed by the certificate authority, which the user implicitly trusts. To forge a certificate that specified your or your organization's name, an attacker would have to convince the certificate authority to issue a certificate under your or your organization's name, and this is presumed to be quite difficult.

Lie Ryan
  • 31,089
  • 6
  • 68
  • 93
2

As pointed out by @王庭茂 and @LieRyan, you need some way to prove that the public key that gets uploaded with the license file actually came from your company and wasn't planted there by an attacker (in your case, someone trying to forge a license file without paying). The solution to this is to have your public key made into a certificate.

Looking at your use-case, I don't actually think that a publicly trusted Certificate Authority is what you want. Instead you should set yourself up a private Certificate Authority hierarchy (this can be done in-house for free and with minimal effort with OpenSSL). It's not as scary as it sounds - a CA is really just a public key file that OpenSSL can use to sign other files or certificates.

You should set up a few OpenSSL CAs like this: CA Hierarchy then embed the Root CA certificate in the source code for your application (this is called certificate pinning). The Root CA exists to be an anchor of trust, but doesn't actually do anything other than signing the certificates of sub-CAs. In most cases you can actually take the Root CA offline after you've created your subs. The sub-CAs are the ones that you use day-to-day to sign stuff. Usually the sub-CA would sign signing certificates that you use to sign the license files (creating another layer in the tree), but in your case you can probably get away with having the sub-CAs sign the license files directly if that's the only thing you're using them for. This way you have the flexibility to use multiple keys as you mention in your point #2 (each sub-CA is basically just a signing key), or even to remove a key and replace it with a new one - if you ever need to - without any disruption of service or needing to send out patches.

To actually implement this, you'll have a sub-CA sign the licence file, and then send the licence file and the certificate of that sub-CA together to the customer. You'll need to link OpenSSL into your application so that it has the logic to validate a certificate. When you upload a license file to the application, it will validate that 1) the license file is unmodified (aka check the signature), 2) that the signature matches the key in the sub-CA cert, and 3) that the signature on the sub-CA cert matches the root-CA cert that's embedded in the application's source code. You now have a proper, secure, Public-Key Infrastructure without any need for the application that's accepting the license file to have internet connectivity!

I'll also address the preemptive question "Is it really worth all the hassle?". The answer is: I don't know, that's up to you. How much do you charge for a license? $5? Probably nobody's gonna bother to crack your license format. $500? You can bet people will start publishing fake keys online. From your question, you've obviously decided that it's worth going down the public-key route. My opinion is that with security you should either do it properly, or not at all. Providing something that looks like security, but is easily broken, won't prevent even mildly skilled attackers, and will give your customers a false sense of protection (maybe leading to outrage when they find out).

Mike Ounsworth
  • 57,707
  • 21
  • 150
  • 207
  • 1
    Agree all but one point: verifier doesn't necessarily use OpenSSL. There are **several libraries and utilities** that can check X.509-based signatures, and you might use different one(s) depending on the language(s) you are using and/or the platform(s) your code is running on. Note some implementations, though not OpenSSL to date, will try to use Internet to check revocation (OCSP and/or CRL) which is probably unnecessary if a single party does all signing. – dave_thompson_085 Jan 30 '16 at 07:33
-1

When these keys are ment for other applications to connect with your service read about two/three legged authentication. (OAuth) https://www.rfc-editor.org/rfc/rfc5849 (Version 1) There is already a version 2 but I have no experience with version 2

Klaas
  • 1
  • Your answer does not address the question posted ("is it secure to ship a public key with a license file?"). The question is about delivery methods, not about authentication. If you meant to implement a service where a user can log in and download the public key (using OAuth) then please reword your answer – Purefan Jan 29 '16 at 14:59