I'm writing a web app in ASP.Net that creates a licence key for a Windows app written in Delphi. For simplicity I'm going to use a email address and date.
I want to encrypt it in C# and email that info to the person then when the Windows app starts up the person enters in the encrypted string.
Every time the Windows app starts it checks that licence by decrypting it and comparing to todays date.
How can I do this to ensure the C# encryption will decrpyt succesffuly in Delphi?
"the world was full of bad security systems designed by people who read Applied Cryptography"
While the trivial answer is 'use the same algorithm and make sure you have the same keys and initial vector', this answer only exposes the true problem you are going to have: How are you going to protect the encryption key? Mail it along with the license? Embed it in the application? The truth is that there is no protocol that can bootstrap itself w/o a root of trust, either a public trusted authority or a shared secret. A shared secret is easy to code, but complete useless in practice (which means AES, 3DES, XDES or any other similar cipher are not the answer), so you need an scheme that starts based on public key cryptography. For such, to encrypt something for the beneficiary of the license, you need the public key of the said beneficiary, which would make provisioning difficult (license site sends public key, you encrypt license, send email etc). It is much better to send the license in clear text, but signed with your private key. Then your application can validate the signature on the license and use it, if not tampered with.
S-MIME is such a scheme. PGP is just as good. Writing your own code in C# and Delphi is possible, but strongly discouraged. See Cryptographic Signatures.
AES for Delphi and AES for C#.
You can use standard RSA or DSA signature algorithms to do what you want. For C#, these are standard algorithms built into the runtime. For Delphi, you have some choices. See Free Encryption library for Delphi.
Once you have chosen an encryption library for Delphi, you can now do the following:
The C# server signs the user's e-mail address and date using the chosen signature algorithm with your private key.
The Delphi client verifies the license using the same signature algorithm.
Once the Delphi client knows the signature is valid, you can then test the e-mail address / date and decide whether or not to allow your program to run.
I have done exactly the kind of signature verification you want/need using the DSA algorithm, LockBox, and C#.
One thing to be aware of is that C# encryption uses big-endian numbers, while LockBox / Windows CryptoAPI uses little-endian numbers. This probably means you need to reverse endian-ness of both the public key variables and the signature itself before sending it to the Delphi client for verification. Check your crypto library documentation.
One last note: others have proposed using symmetric encryption algorithms like AES / 3DES / etc. The problem with this approach is that your "secret" encryption key is shared between server and client. It is possible that someone could recover the key by reverse-engineering your compiled EXE and then create a "key generator" - a worst-case scenario being a fake activation server that passes out "authentic" encrypted licenses. By using assymetric crypto and keeping the private key secret, you won't have this problem. Users would have to crack every new version of your EXE or else pass around signed authentic licenses - much more inconvenient.
Use the same encryption / decryption algorithm in both delphi and c#.
You can either find the code for an encryption algorithm for C# and then convert the code in the decryption algorithm into Delphi. Likely if you pick a popular encryption you'll be able to find both encryption and decryption algorithms already in many different languages.
Related
I've been tasked with adding in a system that allows my company to encrypt files so that we can send them to a third party and they can run some operations on our data. The third party has given me a public key in this format,
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.18 (Darwin)
mQGiBFU1gfQRBACekfIt7mSynzBi0C2hIbvWM6mMh80ypw8NNvdCpOIfSwLVavej
YIESXe5yLGzWUoTnHALa5JHLJ2C3faeDHRBikXRESycRHz0itz3L/mlyIPLo7T1n
4zr2wUL+h0ZEmuhLeVBD+yLKzy68suEWXCcTkeh71vYG1r77RFJLtQHIfwCgu9DW
uJC8IHzXMrspotFIb0XF/VsD/iqdfRgdu7CkvUflwQsT66CmZcyfkkZkWpHXZoov
GP3ZCVKPfGEZqlThwuqgBCBbtsyZFSSmF8m5qjL/Dtz+t3/fxxTo1lXRr9P4f4Pl
n3OYQh+iOs1Z+7nnAZ4mulU1eRPYUY21e+UwKi+hd1Qe1ADOaH/9JVS8nrodePCO
qBFvBACXKEWpP937fZv1hGdqZ2OUM44RIf0PGbQwyG8a+DsksJgd0oY+sb5nTaB/
CgsEFgIDAQIeAQIXgAAKCRDEcHC8uF0CrVnTAJwLdvuBjv/Z8lySVZS7jInljU9y
sACdEtxmspV/GH7EDY0KtIydy3Vn8/eIXgQQEQgABgUCVTWCPAAKCRArjD/JWo9s
KvwNAP9CkZgMGn98wwMAixW5tIVA+J5kvdxnleg/wrR9xHsFYQD+KMraOkHSk10p
1EckgFK6LTuVqMvUoK9Gvr8v0rrHucW5Ag0EVTWB9BAIAP12dtlu0EuQ4s78ZWhM
cDJmpqot5FbMecPF20V5LsDFYbLGylEPPFFxNhwsc/l0Rlvg7auH2fcLSZf5hEp9
NsBhgWD532CAim9bFYF1s2bbjlZ7jUQD/Dt+9j1d9YrgCkF2/9er7RyfYwsRlVDQ
1nRCFLoQWLqisoILG65oloVtjNg6xftyLaLb6UuluW8dRM7q/9EvE0xPAX1ukc33
iGDWeMUR0JHyuM1QiN4IhOHKjP6Oqy+lJWtgoCQmxPJ2+Qj6b34wtsfD9vh3xLef
68ReXEOlfQ01tv6hQCrK/ZdvPLk38kVnwPOEJl/Hgj5eiVM3ioOlmBQoXKSpXyXI
wMKnovOEqJ2btp39XNpjjcV80RZiAJyAhNz2EynZk15QhOnabo9gdsiaMpBZdSdc
gDHowOXsWxzaVESs+SwJf/N2fa3j1UTDxCKkq5TOofvOfyPAYYASstmPw1v7xIcV
zn2nkKfBk1EnFM5PfwQAfXKUTx6BrZmITwQYEQgADwUCVTWB9AIbDAUJAsfqAAAK
CRDEcHC8uF0CrTI6AJ4oAZ2y4Pcahp+SRSNSW7Nijqdv2QCgnJ2EauQgU+rSyHyy
lkp3zJGdJTU=
=k/9l
-----END PGP PUBLIC KEY BLOCK-----
Can I stick this text string directly into say the RSACryptoServiceProvider class in C# as the public key? Or is there more to it than that? I haven't worked with PGP before, and I'm trying to know what I need to do in order to get data encrypted using this key.
Although OpenPGP takes advantage of RSA and other standard algorithms, you cannot use the default C# RSACryptoServiceProvider. RSA is only one possible algorithm for OpenPGP, and furthermore you need some symmetric encryption algorithm like AES (which would also be available). But there are further problems: you'd need to implement a generator for the OpenPGP message format, and OpenPGP defined its own cipher mode. Implementing all this on your own will not only be a hassle involving incompatibilities (an incomplete list exists in the RFC, but also has lots of ways to include security issues (and a bunch of further interesting attacks have been proposed and mitigated with existing implementations like GnuPG).
If you want to use OpenPGP from C#, in the end it boils down to following alternatives:
use GnuPG through GPGME (but the wrapper still seems to be in alpha state),
use BouncyCastle which has native implementations of several cryptographic protocols including OpenPGP for both C# and Java, but the C#-implementation seems to be less wide-spread and is not as capable,
SharpPrivacy is another implementation, but seems dead
interface the GnuPG command line directly
All of those have advantages and disadvantages. Probably BouncyCastle will be the best way to go, if it does not support the required features, you'll probably have to drop calling command GnuPG on the command line.
There seems to be a C# library for this on GitHub but it is a few years old. I am sure it can point you in the right direction if you want to implement your own PGP encryption.
https://github.com/da2ce7/SharpPrivacy
There is also a codeproject article about it but it is quite old and references a site that seems to not be up any more. Here is a link to that one for reference as well
http://www.codeproject.com/Articles/4284/SharpPrivacy-OpenPGP-for-C
.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
License for C# desktop application
I want to make my program lock after some days of trial use and if a user purchase a license, can use the program for some months.
I dont know a way to do this. An idea is to make a local temp key when the program is installed, and lock it after the days passed(the problem here is that user can change date and time of his computer.. the philosophy of the program is to be used online and offline, so i cant compare dates from my server to the computer).
And the other thing is, how to make a license service. I can generate lots of serial keys and then when a user pays i can give him a serial, and every time the program starts i can check if the serial is in my web service.
Am i in a good road?? Any suggestions?
If this application is written in C# and you want to write your own licencing functionality, you will first need to obfuscate the executable before it is deployed. This is to stop people reading your CIL code (stored in the .exe) with a disassembler.
To licence the software you will want to choose an encryption method. For such encryption a symmetric method is essentially equivalent to an asymmetric method (as you have to provide the key in any case). The encryption method can be chosen using
public enum EncryptionAlgorithm { Des = 1, Rc2, Rijndael, TripleDes };
for each of the methods and their details, see Wikipedia. The Rijndael encryption algorithm has been designed to replace the aging DES algorithm. Like DES, it is a block cipher. It uses 128-bit, 192-bit or 256-bit keys and is a good choice. In the following I will assume that you will not be storing the encryption key in the code (hard coded) but supply it in a separate file (a ‘product key’); so you will supply two licence files the product key to enable decryption and the encrypted licence file.
Once you have chosen an encryption method, it is common-place to come up with a hash or algorithm to work on the product key/initialisation vector (IV); you take a 128-bit key (for example) and scramble it using some method/transform. The key (that is randomly/pseudo-randomly generated for each user you deploy the software to) is then used to generate the IV.
You then use the 'random' key, the IV and the selected encryption method to encrypt some licence text (that includes licence dates).
internal ICryptoTransform GetCryptoServiceProvider(byte[] bK, byte[] iVec){ ... }
To decrypt the file using your method you essentially perform the reverse process. One thing to note about licencing, is that you should not spend too much time worrying about people cracking the software. Make it very hard using a method like the above, but don't invest too much time coming up with an ever increasingly complex methodology because if some (admittedly very talented) hacker wants to crack your code it is likely he will. Moreover, you have to assume the user will not break the law and share licence files! I cannot comment from experience on using an external company to run the licencing of your code (I have always written my own), however it is likely to be an expensive option.
I hope this is of some help.
Although it highly depends on your exact requirements, target technology (Winforms, WPF, Silverlight etc...) I would suggest using a third party licensing component such as Quick License Manager, Licensing Pro dotNet.
While rolling your own solution is going to be cheaper, the possibility of it being cracked or circumvented is much higher. To use a third party solution means you have an external team or company dedicated to keeping the licensing model secure and more reliable.
Best regards,
After reading this post regarding the use ECC to implement the hashing using aa private key I set about trying to find an implementation of ECDH and came across BoucyCastle.
Unfortunately documentation is minimal (as in zerow!) and I'm unsure what I'm about to accomplish is completely correct/valid.
We want to simply hash 4 strings which will be the users registration information (Name, Company, their company ID and their account ID which are both 12 characters long) which will then compute a serial they can use to activate our software.
I have generated a key pair using PUTTYGEN.exe but I cannot workout how to apply this with BouncyCastle, which class can I use to get started? Are there any examples out there?
So far I've concatenated the information and computed a MD5 hash of it (using the .NET classes) I cannot use the new VISTA enhanced API functions as we target XP still - .NET 3.5.
Anyone have any ideas?
I think .NET has the RSACryptoServiceProvider class which is a full RSA implementation.
There's sample code for your particular application here:
http://www.codeproject.com/KB/security/xmldsiglic.aspx
In this example they use MS's sn.exe tool to create the key.
So far I've concatenated the information and computed a MD5 hash of it (using the .NET classes).....
That statement in itself worries me. MD5 is seriously crackable - not just theoretically but practically. Please, please don't use MD5 for secure hashing. Use SHA-256 or SHA-512 and here's why
Also the post you linked is not quite true - yes symmetric algorithms use the same key to encrypt/decrypt but public/private key is not a magic bullet.
1) Public/private key is slow
2) Most publicc/private algorithms just encrypt the symmetric key and then use symmetric encryption for the data because it's much faster
The point is that a good hashing algorithm is non-reversible and hence very difficult to crack so is perfectly fine for your purposes. However, I'd suggest using a SALT, which is a cryptographically random number to add to your user data then hash that data as it makes your data much safer against dictionary attacks ( where hackers use well know terms and variants to crack passwords )
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.
I understand better some concepts when I write toy programs for isolated aspects of the problem at hand. For instance, for encryption you can write a program to encrypt and then decrypt a string.. and see that you get the initial string.
What toy programs do you suggest that I write to understand certificates? (server/client interaction, ssl communication, signatures, etc) And/or what .NET namespaces should I explore?
(not important for the question, but I use c#)
Create a symmetric key and encrypt/decrypt something with it. Modify the encrypted byte [] and try to decrypt it. Play with different padding and modes and repeat a few times.
Create/Save/Load certificates and private keys.
Verify the certificate chain for any certificate you find to see the most common kind of errors.
Create a symmetric key, encrypt it with the public key of one cert ("client") and the private of another ("server").
Create a message that sends the above key encrypted with the "server" private key, then some encrypted text and sign the whole thing. Then decode and verify this using the "server" public key and the "client" private key.
Namespaces?
System.Security.Cryptography
System.Security.Cryptography.Authentication
System.Security.Cryptography.X509Certificates
A few interesting types:
RSACryptoServiceProvider
SymmetricAlgorithm
RijndaelManaged
ICryptoTransform
X509Chain
I do not agree with the given answer. In order to understand certificates, you have to understand the infrastructure behind it (called PKI, Public Key Infrastructure). That means you have to read some material about first
How does public key crypto work (in general)
Why are PKI's needed
What is a certificate and why do we need it
Programming this stuff doesn't make sense if you dont know the concepts behind it.
You compare it to encryption/decryption. Both are blackboxes where the user does not need to know how it works (internally) in order to use it.
However, certificates and PKIs are different. in order to be able to user them in a practical and mostly secure way, you need to first grasp the concepts (by reading, but dont be afraid reading a few wiki pages and asking a few questions here will get you more than halfway) before you can program it.
edit after comment:
Yes, toy programs are always nice to grasp the concept in practice. What comes to mind:
Do a public key encrypt/decrypt (basic)
Do signature/check signature (i know it is the same as the previous one, but it is principally different) (basic)
Try to connect to a server and do the SSL handshake yourself (advanced)
Try to connect to a server, fetch the certificate and check the validity through the whole certificate chain (moderate)
Try to create your own self-signed certificates (moderate)
Try to use other encryption algorithms besides RSA, try DSA, El-Gamal, Elliptic Curves Crypto (moderate)
Implement a diffie-hellman keyexchange algorithm (advanced)
And once you're done with these i think you'll quite a reasonable understanding of the whole thing.
If you're still curious, you can always dive into the more advanced stuff like the math, like how you cheat, algorithm correctness proofs etc.
Btw, i just stumbled over a recent discovery concerning SSL/TLS and since you're working on that subject, perhaps you'll like to read this small article:
http://blog.ivanristic.com/2009/11/ssl-and-tls-authentication-gap-vulnerability-discovered.html