Symmetric and Asymmetric Cryptography - c#

I'm looking for an advice regarding cryptography.
I'm working on a .Net application which I need to create a license for it, so I plan to create an encrypted license file which my application will use to know if it is licensed or not.
Handling license is as following:
License Generation:
Generate unique symmetric key.
Use symmetric key to encrypt license information.
Use asymmetric public key to encrypt symmetric key.
Write encrypted symmetric key and encrypted license information to file.
License Decryption:
My application will read license file.
Decrypt symmetric key using asymmetric private key which is embedded
xml file inside dll.
Use decrypted symmetric key to decrypt license information.
My questions are:
If the dll which is responsible for decrypting the license has the asymmetric private key as xml embedded resource, is it possible to spy on the dll to get the key and generate a new license?
Is there another technique I can use which is more secure?

As a very general overview, the simplest way is to sign (there's no real need to encrypt anything really) the information with a private key, and verify the signature with the corresponding public key. That's it. The private key is kept safe and no valid new signatures can be generated without it, so if someone changes the signed information the signature becomes invalid. There's no need for extra symmetric encryption on top of it - it's pointless work as far as I'm concerned.
There are plenty of libraries that already do this easily enough, but it's also not that hard to do it manually. https://github.com/dnauck/Portable.Licensing is one I used before.
Edit: also yes, in general it's very easy to decompile .net assemblies, including extracting resources from them.

Related

How to encrypt generated RSA private key and decrypt in c#

I have seen articles regarding encrypt/decrypt data using Private/Public key. All I want to do is to just encrypt a generated RSA private key already stored in a file. I have been browsing widely to get an idea how it can be done but with no luck.I presume my question is rather an unusual one. Please help!
First, you need a *Key derivation function, to turn your password into a symmetric key which you can use to encrypt your private key. If you solely use the .NET framework, you should use the Rfc2898DeriveBytes class for that. If you are able to use BouncyCastle, then SCrypt would be preferred.
Then you can encrypt your key, prefreably using the AES algorithm.
Some usable code sample can be found in this answer

Decryption-Only method in C#

I'm looking for a secured way to implement a license file for my application, with flags and features. I read about Asymmetric key mechanism in C#, but the RSA purpose is little opposite from what I need.
I want to generate a license file: encrypted cipher. The application would have the key to decrypt the file - but wont have the ability to re-encrypt it. Everywhere I checked, the example shows how party A generates public and private keys and passes the public key to party B so it can use it for encryption. It's probably there between the lines, but I can't see it.
I checked this one: Encrypting and Decrypting
I can find a way to use the code I see to implement it, but I'm not sure it's really secured.
You can still use asymmetric encryption: generate a public-private key pair, encrypt with the private key, and the client (the "application" as you mentioned) can decrypt it with the public key.
Of course, a public key (and the private key too) can be used for both encrypting and decrypting.
But re-encrypting plain text with a public key would generate a completely different cypher than a cypher encrypted using a private key. Decrypting and re-encrypting with the same key would produce a different result, and so it's useless.
What dcastro said above is absolutely correct, and you should give him credit. I just want to add to it, but can't yet comment. If you encrypt the license information with our private key, and distrute your public key with the application, you would be able to decrypt the license information. Without the private key, it wouldn't be possible to re-encrypt a different version of the license that could be decrypted with the public key without using the private key.
Asymetric encryption works like this.
Information encrypted with public key can only be decrypted using the private key.
Information encrypted with the private key can only be decrypted using the public key.
Now for the kicker.. You're probably going to want to encrypt your license with a symmetric algorithm, and encrypt the key needed to decrypt it with the asymmetric algorithm. This way the length of your license data isn't limited by the asymmetric and the symmetric key can be customer specific.
Like I said, give the credit to dcastro.

Encrypting with app public/private key in .net

-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

Can I use the assemblies PublicKey to decrypt a string encrypted with the corresponding PrivateKey?

Signing an assembly in .NET involves a public/private key pair. As far as I can tell from what I've read .NET uses the RSA algorithm and the private key to sign the assembly, checking it with the embedded public key.
I know how to retrieve the public key (Assembly.PublicKey). I was wondering, if that key could be used to decrypt a short string that contains some data encrypted with the private key.
The docs I've read so far (e.g.) seem to imply that only the other way round is possible: That I would have to use the public key to encrypt and the private key to decrypt - but I don't really want to include that in the assembly, do I.
I guess it would be ok, if I just signed the string. But how?
I'm a bit at a loss how to start this. Does anybody have a code snippet?
Also, encrypting / signing of the small string would ideally happen in PHP, since I want to offload that to a web server and all we have so far is your generic PHP/MySQL hosted website.
Use Case: I'm trying to come up with a lightweight licensing scheme for a software we are about to release to beta testers. Since the software will probably be freeware, all we really want to achieve is
know who has the software installed (email address)
let the software expire after a given period, after which the user will have to get a new license
this is as easy as filling out a form and waiting for an automated email with the key to arrive
we are trying to reduce the likelyhood of old versions coming back to bite our reputation / haunt us
Being able to encrypt a tuple (expiry date, fingerprint) and decrypt that at startup would make an easy licensing module: The first time the application is started, the user is asked for email address, name, organisation. This information is posted to the webserver along with an md5 fingerprint of some system info (nic, computer name, assembly major and minor version). The webserver answers by email (checks validity of email address) with an encrypted version of the tuple (expiry date, fingerprint) that is then saved to disk. On startup, this can be decrypted and compared with current date and regenerated fingerprint.
EDIT: OK, so I don't have all the answers to my question yet. But it looks like .NET won't make it easy to use the private key for encryption (if that is at all possible, the answers don't really agree on that).
The route I will take is this (based on my use case):
I will use the private key to sign the license.
I will use the public key to verify the license was signed by the private key
I will post another question aimed at PHP devs on how to use the .NET keys (produced by sn.exe) to sign some text
I am not really worried about the user seeing the license, as it is a hash anyway and computed from stuff he allready knows. All I want is to make it too hard to be worth any bother for your typical building architect to copy my software without me knowing (remember, the software will be freeware - all I want is a paper trail of who has it installed...)
Thank you very much for your answers.
You cannot decrypt using the public key. That way, the whole point of "public" would be lost.
(You might, however, be able to sign something using the private key, then verify the signature using the public key. That's what the framework uses the keys for - the assembly is signed, and the public key is used to verify the signature.)
This can be done using SignedXml http://msdn.microsoft.com/en-us/library/ms229745.aspx. At a lower level you can prob use RSAPKCS1SignatureDeformatter and RSAPKCS1SignatureFormatter. These work by encrypting a hash of the data then comparing the data with the (decrypted) hash the other end. I believe the hashing is used because private key encryption can only handle small data. Not sure about reusing the assembly public key, if it is causing problems just use a separate key pair.
Word of warning, check out this as these classes can result in 20 second hang ups! http://www.pcreview.co.uk/forums/thread-3428177.php
This approach is vulnerable to the signature verification code being tampered with using Reflexil but that is another matter.
I wrote the following but rereading I think you already got this: You aren't really trying to encrypt or hide data from the user, you want to stop them from creating or tampering the license. You are right that a public private key encryption algorithm can be used for this. This is known as Signing using a private key (server side license generation). And verification of the signature using a public key (license checking in the app). I mention this terminology as it'll help with research.
Not in .NET.
In many traditional public-key encryption algorithm, like RSA, you can encrypt and decrypt both ways, typically one way is called "encryption" and the other "signing", even though you actually end up with an encrypted version of something both ways.
However, in .NET the RSA implementation has been crippled, and when signing will only produce digests of the input, not the full processed information.
It seems there's some disagreement about what can and cannot be done with RSA, so let me edit my answer to be more specific.
I'm talking about RSA math, not any particular RSA implementation.
RSA math allows you to encode information either of the two keys (private or public), and the encoded data can only be decoded with the other of the two keys.
Typically, you encode with a public key, encrypting the information, and decode it with the private key, decrypting the information. Or, you take a hash of the information, encode it with the private key, signing the hash, and decode the hash with the public key, in order to compare and verify the signature.
Typical implementations does not allow one to do full encoding of data from private to public, only by hashing the data, but the math behind RSA fully allows this.
In RSA Public keys are used for encryption, private keys are used for decryption. You can't use a public key to decrypt anything...
In RSA the only actual difference between a public key and a private key is which one you keep secret.
So you can use a public key as the encryption key and decrypt with the private key, or use the private key as the encryption key and decrypt with the public key.
Encrypting with the private key is used for digital signatures (anybody can decode with the public key).
But as #Lasse V. Karlsen pointed out, .Net might make it more difficult than it should be...
I think both direction are possible encrypt with public and decrypt with private and encrypt with private key. The second is the way how digital signature works.
Warning! This answer is wrong but I'm going to leave it here none-the-less because the series of comments attached are, I think of sufficient interest to others to keep the answer around. Ok it makes me look like an idiot but thats nothing new to me ;) Vote as you wish.
A public key can be used to:-
Encrypt something that can only be decrypted with the private key
Authenticate something signed with the private key
It can not be used to decrypt something to encrypted by a private key. Its for this reason that the Public/Private key system is refered to as an Asymetric system.

How is public key used to decrypt in .NET assemblies?

.NET signed assemblies contain public key, but the public key is used for encryption in RSA, then how does .NET uses the public key for decryption of signed assemblies?
Ok, the signed assemblies contain the hash, but the hash is encrypted using the private key and not the public key. So, why and how in .NET private keys are used for encryption and public keys for decryption. I mean, that all software like RSACryptoPad uses the public key for encryption and not for decryption.
The public-private key pair is not used to encrypt the whole assembly. Instead it is used to sign the assembly.
Simplifying a little, to sign a file - such as an assembly - you take a hash of the file and then ecrypt that hash with your private key. Someone using the file verifies your signature by making a hash of the file themselves and then decrypting your encrypted hash using your public key and confirming these two hashes are the same. This proves two things:
The assembly is from who is claims to be from - i.e you - as it has been produced with your private key.
The assembly hasn't been altered by someone else as the hash you made when you released the assembly is the same as the current one. No-one can alter the signed assembly since they would also have to make corresponding changes to the encrypted hash which requires your private key.
There is a lot more detail about Digital Signatures in this Wikipedia article.
The great thing about public-private key pairs is that they work either way around. So something encrypted with your private key can be only decrypted with your public key but also something encrypted with your public key can be decrypted with your private key. This latter use means that if someone wants to send something to you and only you then then can encrypt it with your freely available public key but they know only you with your private key can decrypt it.
As the keys only work as a pair - making the encryption asymmetric - someone else can't simply reverse the encryption they've done with the public key to get the message to you.
The idea is that a signature can only be created using the private key, but after that anyone with a copy of the public key can validate the signature. No decryption is required for a signature--the signature is simply added on to the plain text assembly.
The purpose of signing assemblies is to verify their source. If I sign my assembly then send it to you, you should be reasonably sure that's its come from me and it hasn't been tampered with along the way.

Categories