I'm trying to determine the best course of action to implement a simple "licensing" system with a partner of mine. The concept is:
Generate an encrypted value based upon several internal hardware components. Have the customer send this value to us which we will implement into our key generator. Once we have that, we add any other restrictions on the license (user, expires, etc.). From there we generate a file which we send to the customer they can add to their installation and voila, happy people about.
I have the first part all done. My next part is trying to figure out which encryption methodology I would need to use. I already know Symmetric Encryption is pretty much the only route I can take. Most of the information I have found involves .NET already creating a key from its own internal methods.
That's a bit of background, my question is: "Which encryption method could I use which would allow me to encrypt the restrictions based upon the "id" I was given from the customer's computer?" I'm writing this in C# by the way.
You say you know you need symmetric encryption but you would be wrong. With symmetric encryption the code checking the license has to have access to the secret, which means if your code is reverse engineered someone can not only figure out where to remove the checks, they can generate and sell license keys that are indistinguishable from the ones you make.
Use asymmetric encryption, or a secure hash. And don't try to use the customer-specific hardware information as the key, instead prepend or append it to the other data. You're essentially creating an access control/rights/privileges list file coupled with a message authentication code to verify its source (you).
I recently did something very similar to this. I used AES to generate a value based on a private key using an internal customer id or order number as the IV used to encrypt the value.
Instead of an order number you can use some form of checksum from your first step so it's not something that's stored as the IV. That way if the file is hosed or if they transfer the software to a new computer - either way will invalidate the file.
Something you might be careful of though is how closely you tie the installation/license to the hardware. You don't want to punish a legitimate user simply because they upgraded their motherboard.
Related
I want to do the below. What is the best way to achieve this?
I have a desktop app in C# which will be installed on multiple client machines.
The application is capable of doing an operation X but it needs some auxillary info which it can read from a file. This auxiliary info essentially provides some specifics that identify that machine where the operation should be run and what operation to run etc.
I will work with the client to get some of this auxilary info about his machine (say hostname/ip address etc) which I want to put in this file along with other info and generate it on my machine and share it with him/her to provide it to my software. I want to encrypt this data so that the structure of the data is not obvious to somebody who opens it. (I will get some of the machine identification info from the client, either via phone or email).
I want to somehow encrypt and secure this file such that only I can generate the file but any of my installations can read it. But since the contained info is specific to a machine it will be executed only on one machine (other machines will read but reject it since the given hostname/ip etc won't match that machine)
How do I do this? I want to make sure the below:
Only I can generate this file.
I need to somehow authenticate that this is generated only by me and not by somebody else.
But my software on client machines should be able to decrypt this.
I don't want to take a password from the customer etc. all the decryption logic should be in the installed software itself. I want to code it in.
When I researched this online, many talk about public and private cryptography but there they talk about encrypting with the public key and decrypting with the private key. But I don't think this will work since decryption is being done by my software at the client machine and so I shouldn't put the private key in my code. Because, from what I read, private key can generate public key so somebody could potentially generate that instruction file if I do this.
What is the best way to do this? Can I encrypt with private key and decrypt with public key? Is it ok if somebody gets hold of my public key (say they disassemble the C# code)? Any other good ways to encrypt and authenticate such that I hold the private data with me but code only harmless public keys/data in the application?
TIA.
Who are you trying to protect this from?
You are giving the end user your application binary. Assume they can decompile it and work out how it works. Or step through your code in a debugger, with access to the contents of every variable. Assume that an attacker can learn everything they need to know about how it works.
At best I would recommend creating a hash of the machine details and a salt value. Then create a signature of that hash.
Keep the salt and the public key of the signature as a constant in the application binary. Maybe XOR values together so an attacker has to think a little about how it works.
But anything more is pointless. Any attacker with more skills will just patch your program to delete the test entirely. So I wouldn't bother building anything too complicated.
Giving someone a program, and preventing them from using it, is like trying to make water not wet.
You have two questions
How do you encrypt the information, and
How can your client make sure the information came from you.
Those are orthogonal
I'll address the second on first - it's easier.
First, hash the file, and add the hash to the payload. Then generate a public/private key pair, then encrypt some known (but non-trivial) information with the private key and add that to the payload. You can distribute the public key with your app. If your app hashes the file and the hashes match and it can decrypt the known information and make sense of it, then it came from you and no one has changed it.
This is known as a digital signature. If you look up a digital signature provider and follow the docs, it should just work.
The encryption problem is more of an issue. There's pretty much no way to do what you want. If your app can decrypt the information using information you distribute with the application, then a determined bad guy can extract that key material and decrypt it.
However, you can use the RSA key container on the client to do the encryption when you install the app. The process is similar to using encrypted sections in a web.config file. Since you won't be following the encrypted config section cookbook the process is complicated.
I've done this before, but it was several jobs ago, so I don't have anything I can show you.
But, it will be encrypted so that it can be read only where it was encrypted. No two installations will recognize each others files.
That said...
Encryption seems like a heavy hammer to prevent your customers from being able to guess "the structure of the data [so that it] is not obvious to somebody who opens it"
Unless you have something worth protecting, you can probably get away with obfuscating the data. For example, you could have the data as JSON, but then use GetBytes on a Utf8Encoding to get a byte[] and convert that to a hex string. A determined hacker could decompile you code, figure out what you've done and reverse it, but that doesn't seem like a threat you really need to worry about.
So at my workplace, I have a .NET based web application, that has to pick up an encrypted parameter in a querystring.
Those supplying the encrypted string is an external contractor and they prefer (almost demand. cant change contractors though, the higher ups decide that stuff...), to use Microsoft's Crypto API to encrypt the string.
Well, fair enough, AFAIK I can decrypt that with C#, but after endless searching I am still at a loss on how it works.
That means I cant even supply example code, and I am stuck in this bind until I can decrypt this string.
What I have is:
I have the common password they encrypt with and I have to use to decrypt it with.
Encryption settings are: "CALC_AES_128" hash: "CALC_MD5". The string is encrypted, then hashed.
So I want to unhash it, and decrypt it.
I know its a lot to ask but how do I go about it?
Your external contractor doesn't know what he is talking about.
Hashes are used as a trap door function, a way to recognize something without been told what that thing IS. It is a digital fingerprint. The way a CRYPTOGRAPHICALLY SECURE hash is made, means even given the hash and the algorithm it is difficult to create an object that matches the fingerprint.
AES is a non-deterministic cypher. The non-determinisism comes from the Initialization Vector, which is meant to be a random number each time (not hard coded from a die roll, ahem Sony). This means for all intents and purposes, the output of AES is pure random (unless you have the key). Good cyphers are all designed to produce data that is statistically random (thus there is little data to form an attack from).
So by feeding data into a function that creates random data, then putting it into a trap door function, you have produce something that is truly difficult to decode (difficult in this sense is mathematically, you actually need more energy than exist in the universe to compute this).
As for how to send data across in a secure manner (secure as in against prying eyes on an unsecure network) in the query string? There is a well known protocol that .net supports that does this very well. Its called HTTPS.
Im using some 3rd party Dll's in my code which require a license key to work.
The license key needs to be passed into the methods when called or they don't work.
However I have written my code in C# which means this license key can be retrieved by decompiling my code.
Is there any way for this license string to be prevented from being decompiled?
(adding as an answer because the message is too long for a comment)
There is no way to completely block access to this string, you can only make it harder. Even if you encrypt it, your program will need the ability to decrypt it, which means that anyone skilled enough can access and reuse the decryption mechanism to get the key in clear format. Or they could even simply read the decrypted key from memory.
You could store the License key in app.config and then encrypt it: http://www.codeproject.com/Articles/18209/Encrypting-the-app-config-File-for-Windows-Forms-A
That probably gets you the most bang for the least buck.
Don't worry too much about it. If your application has access to the key then anyone with access to the binaries and enough time can get that key.
Keep in mind is not your licensing scheme which is at risk, is the licensing scheme of the 3rd party one and thus you have to rely on the applicable laws. If someone decompiles your application and gets access to the key they're breaking the law and it's something you can't prevent.
Your app has the legal rights to use that third library, breaking it has to be handled by law, not by protection, and it's a violation by the terms of the 3rd party licensing scheme. You can go into a certain length to protect it but in the end the responsibility is not yours as there's no way the data can be completely protected (your app needs to know that key and so, at some point, that key will be available in plain text for anyone with access to the code to pick on it). That is true even if the app was entirely written in assembly language.
Add strong verbiage to your license agreement against de-compiling and/or using any licenses that you have acquired in their own software. Require users to electronically accept these terms. Record the timestamp and IP address of each user that accepts these terms on your own server.
If you wanted to add some basic obfuscation in addition to this, that it ok too. But the main point is that as a licensed re-distributor of this component, you are making a concerted effort to prevent others from using your key.
Here's something simple without encryption, to stop a plain-text view of the license:
Store the string in your code and do some replacing before using it, for example:
string LicenseCode = "croftycot";
// Use license code
CallUsingLicense(LicenseCode.Replace("o","a")); // Change to real code: craftycat
You can get more complicated if you need with a regular expressions, mixing a few strings together etc.
-new- I found another use. Theres some data submitted to me via HTTPS POST data and i'd like to store it in my db (Such as mother maiden name that customer support may need to read later instead of spelling incorrectly checking if the hash matches). I only need that section encrypted and not the entire DB and using a separate DB may not be worth it. Question: How might i use a premade public key to encrypt a symmetrical key + text using .NET? (the rest is for context, i just want an answer plz)
-edit- I have done symmetrical encryption before. How do i encrypt the symmetrical key with the public key? a nice bonus is if you can tell me how to generate the public/private key in a separate app so i can create them and store only the public key in my a app.
I am considering having cheaper less stressed site grab backups automatically from a more busy site. Transferring the data is not a problem since i can use https but i dont completely trust that my cheaper site is as secure or wont have people looking around at my files. I mostly want to protect email address and PM if i have them on the site.
So i am wondering how i can have a public or private key in my app which encrypts the data so only i (or whoever i give the key(s) too) can decrypt the backup. How do i do this in .NET. logging in and transferring i can write in a few minutes but how do i encrypt the stream as i write it?
-edit- it just hit me. The user/pass wouldnt be a secret. So i would have to encrypt my backups before the transfer. How do i encrypt a symmetric key with a public key using .NET. Then decrypt it on my side. Encryption the file with a symmetric key i know how to do.
First off: defense in depth. If you have concerns about the security of the backup site secure the backup site. Mitigating attacks through encryption is a good idea, but it should not be the only idea.
Second, why are you thinking about using public/private key crypto? Normally you'd only use public/private key crypto when attempting to communicate a message from a sender to a recipient. What value does public key crypto add to your scenario?
To encrypt the stream in C#, this page might help:
http://support.microsoft.com/kb/307010
UPDATE:
Absolutely, YES, you have to encrypt the files before they get to the site which you are assuming is compromised.
You believe that the site might be insecure. The assumption you should be making is that the site is your enemy and is trying to hurt you. Start thinking like your attacker thinks. What would your enemy do? If I were your enemy and you handed me a bunch of files to store on your behalf, I might:
delete your files
corrupt your files
read your files
log every byte that comes in or goes out for analysis later
replace your files with hostile files -- in particular, all executable code, scripts, and so on, that you store on this site, you should assume are full of viruses targetted specifically at attacking you
do stuff to get you in trouble -- forge messages that look like they come from you, and so on
Assume that the insecure backup site operators are trying to do all of those things to you. Crypto is a mitigation for some of those attacks, but not all of them.
No offense, but it is very clear that you do not know enough about crypto to solve this problem with any reasonable chance of getting it secure against real attackers. That's nothing to be ashamed of; I don't have this knowledge either. Rather, I have sufficient knowledge to know that this problem is beyond me. There's nothing wrong with trying to learn more about crypto; I strongly encourage that. But if you have a real threat here, and you're trying to mitigate it with professional-strength crypto tools, do not roll your own solution. Go hire an expert consultant in this field who can advise you on what the right thing to do is given the realistic threats that you face.
You encrypt with a symmetric key, then encrypt the symmetric key with a public key, then drop the symmetric key. Only the owner of the corresponding private key (you) can later decrypt the symmetric key, and hence the document. There is no secret stored in the app. The good news is that ther just about a tonne of out of the box products (pgp) and protocols (s-mime) to solve this.
You can use an symmetric key algorithm (AES, DES, Triple-DES) to perform an encryption on your code, and store it a hex in your database (in a nvarchar field). Since, you done need to transfer that in encrypted form to someone else, you wont need to use any assymetric algorithm (like RSA, ElGamal etc.) If you something like RSA, you would also have to consider signing with data using something like PGP.
But, irrespective of which algorithm you use, you would need to make sure your keys are as secure as possible, i.e. your symmetric key for AES, and your private key for RSA etc.
This article, provides an tutorial on how to perform Symmetric encryption with/without Salt.
http://www.obviex.com/samples/Encryption.aspx
I have a piece of data. At the moment, it's an XML file, but the architecture may change. So let's assume for the moment it's a C# Class.
When I store the data on disk or in the database, I need to add some sort of signature or fingerprint or checksum or whatever to ensure that no one can modify the data. The caveat: even an administrator or developer with access to all source code should not be able to modify it.
I assume that since someone with full code access can create a new signature easily (the signing needs to be done programatically, so no manual passphrase entry), the signature somehow needs to contain some additional data. Ideally I should be able to extract this data back from the signature, for example the date of signing and some strings.
My general approach is to use symmetric encryption. I generate a Hash, i.e. SHA-512 from all the fields and then encrypt that hash and my additional data with to get my signature, using the hash as password. To decrypt, my function would generate the hash from the actual data in the file, and try to decrypt the signature. That would not be tamper-proof though as it's easy to generate a signature where the signing date and additional information is still intact.
As I am not an expert on the field, I believe that I am trying to re-invent the wheel, and that it's not a very good wheel. I just wonder if there is some standard approach? I believe that part of my request is impossible (after all, if someone controls the entire environment, that person also controls the system time), but I still wonder how this is generally tackled?
It sounds to me like you want a combination of a digital signature with a secure digital timestamp.
In brief, after signing your data, you call a third party web service to provide an official timestamp and their own digital signature linking that timestamp to your signature value, thus providing evidence that the original signature (and thus the original data) was created on or before that date. With this scheme, even if the original signing key is later compromised, revoked or otherwise invalidated, any signatures that were made before the invalidation are still valid thanks to the timestamp.
A tamper-resistant hardware signature device may help. If the target hardware is fairly recent it may have some support already on the motherboard in the form of a TPM, but there are plenty of vendors out there willing to charge an arm and a leg for their own hardware security modules, or somewhat less for a smart card.
Sufficient security may not be achievable by technology alone. You may need independent validation of the system. You may need remote CCTV monitoring and recording of the machine's location or other physical security measures to detect or stop tampering. You may need third-party code escrow, review and signing to ensure that the code loaded on the machine is what was intended, and to deter and/or detect the insertion of backdoor logic into the code.
The bottom line is that how much money, time and effort you need to spend on this depends very much on what you stand to lose if records are forged.
You need both a digital signature and a trusted timestamp. The trusted timestamp gets a third-party involved to validate the message. Then any attacker doesn't have 'full control' of the whole system.
You may want to leverage PGP by using GPGME (GnuPG Made Easy) a library designed to make access to GnuPG easier for applications.
Jeffrey Hantin's answer is the best I think you're going to be able to do. It's NOT perfect, though:
1) It doesn't stop your black hat from making a totally fake transaction.
2) It doesn't perfectly stop tampering with the transaction. Yes, the new transaction will have a different timestamp but how do you prove the timestamp has been messed with if they clean up the relevant data? Even if you give them some tamperproof receipt (hash & sign the data on it), when it comes to a showdown how do you prove whose record was faked?
You want a digital signature using asymmetric cryptography.
This article seems to have some good examples and explanations.
This is basically what code signing is except, in your situation, it's not code that is actually what is getting signed. You will either have to arrange for a certificate to be purchased or set up your own certificate server.