What instructional toy programs do you suggest writing to understand certificates? - c#

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

Related

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

Encrypt a file base upon a pregenerated "key" C#

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.

Encryption algorithms that don't use a key

I need a simple encryption algorithm that doesn't use a key.
Which ones do you guys recommend?
How about if I use the built in encryption method that forms authentication has? (I forget the method/namespace for it).
Every symmetrical encryption scheme has a key. If you're looking for an encryption scheme where you don't manage the key, you might look into the Data Protection API, exposed in .NET (2.0 and above) as the System.Security.Cryptography.ProtectedData class. It provides symmetric encryption of arbitrary data, using the credentials of the machine or (better) the user, as the encryption key.
byte[] plaintextBytes = GetDataToProtect();
byte[] encodedBytes = ProtectedData.Protect(plaintextBytes
, null
, DataProtectionScope.CurrentUser);
See my other answer here for more detail.
Something outside of the thing being encrypted needs to be used to do encryption, if only because you need that thing to decrypt it later. This external thing is a key. There is no useful encryption without a key. There is only hashing.
What you are calling encryption is simply obfuscation. Even then its going to be encryption where the key is embedded in the algorithm. You'll have to provide at least a simple use case for this before you're going to get any kind of reasonable answer.
rot13 uses a key that's already in the algorithm. That's the closest I think you're going to get.
As an aside to the talks about no key = no encryption...
Maybe what you're really after is automatic and safe key creation and exchange with no user interaction. This can be done by the use of asymmetric encryption, and it works like this:
Scenario: A needs to send a message to B, and wants to make sure no man-in-the middle can read the message.
A and B initiate a conversation like this:
A asks B for B's public key.
B generates a public/private key pair, and sends the public key to A.
A uses the public key to encrypt the message, and sends the message.
B receives the message, and decrypts it with its private key.
This works since the message is encrypted with a public key, can only be decrypted with the corresponding private key. So the public key doesn't have to be secret. If man-in-the-middle picks up the public key, he can't use it to decrypt the message.
You'll probably find tons of information about this if you google for asymmetric encryption...
Fundamentally, ciphers are a way to let Alice tell something to Bob that Eve can't figure out even if she overhears.
This means that there has to be some way for the ciphertext to distinguish Bob from Eve.
Usually, this is a key. Nowadays, it can be a symmetric cipher key that Alice gives to Bob and not Eve somehow, or an asymmetric cipher key that Bob broadcasts so that anybody can encrypt a message for him that only he can read (often used as a way to transmit a symmetric cipher key).
An algorithm can serve as a key, but algorithms are really inconvenient to distribute and keep secret. It's better just to use a standard key.
You could simply obfuscate the plaintext, if you're willing to count on Bob being motivated to read the message and Eve not be. You could do that by zipping a file, for example. Eve couldn't just read it, she'd have to unzip it. This is usually done to prevent Eve from accidentally reading something meant for Bob, on the assumption that Eve is honorable but may make occasional mistakes. The example popping into my mind is the CVS password file; it will prevent a sysadmin from seeing the password at a glance, but it's "the moral equivalent of rot13" if somebody actually wants to read it.
So, to give you a useful answer, we need to know what you want to use this for. How sensitive is the data? How likely is it to fall into unfriendly hands? Who do you want to be able to read it?
BTW, never roll your own cryptography. It's real easy to get something wrong and real hard to notice it. Use standard implementations of standard algorithms.
The problem with keyless encryption is that once it's broken, it's broken for everyone. Take MicroSoft Script Encoder as an example. Once one person figured out how to reverse the encryption and published it, the encryption was broken for everyone (see comments for details on how this isn't as bad as it sounds in this case).
That being said, you can use any keyed algorithm and keep the key a secret and you'll get the same (bad) effect.
If you're really after obfuscation, you can use the PasswordDeriveBytes class to create a key from a password. Then use the key in e.g. AES.

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.

Encryption libraries?

I have been tasked with implementing a PKI library in C# for a company project, and have been unable to find a good implementation of it. There appear to be multiple libraries, and many broken links pointing to MSDN libraries that have been removed. I've seen people using Crypt32.dll, people building their own libraries, people using P/Invoke to access system certificate stores, people extending the built-in libraries, examples that simply don't apply to C# (e.g. Java examples), and commercial libraries.
My question is, which implementation/library is most recommended for simple encryption/decryption of data?
As some background for what I plan to do with it, I simply need to encrypt messages using a private key (.pfx), and decrypt with public keys (.cer). Message signing and authentication isn't required at this level of the project, although it may be in future.
I have seen reference to encryption lengths which make me uneasy. We need to be able to encrypt any length message (within reason, of course!). Is this something I need to worry about, and if so, is there a way to deal with it?
I would prefer not to store public/private keys in the windows certificate manager if at all possible, but if it makes implementation significantly simpler, so be it.
I realize PKI and encryption is a large and complex subject, but I'm hoping for a relatively simple library anyway... (one can hope, right?)
Thanks!
Well, you did not mention that the built-in class doesn't cover your need, so how about System.Security.Cryptography.RSACryptoServiceProvider?
It has a large set qualified ways to asymmetrically encrypt/decrypt streams.
There are several tutorial/guides to take you along the way:
Public Key RSA Encryption in C# .NET - Code Project
RSA Encryption in .NET -- Demystified! - By Peter A. Bromberg
There are countless more to be found through Google.
Update: About the length-restrictments, it's should not be any problems if you just implement the same buffer-algorithm on both sides, encryption and decryption.
Update2: Yes, my example was RSACryptoProvider, but you can use any class that derives from System.Security.Cryptography.AsymmetricAlgorithm, if you want a public/private key-solution. Or build your own... or maybe not :)
Yes, what's wrong with built-in classes?
And if you don't want to use Windows certificate store you can use something like this
RSACryptoServiceProvider rscp = new RSACryptoServiceProvider();
rscp.FromXmlString("<RSAKeyValue><Modulus>key data gere</Modulus><Exponent></Exponent></RSAKeyValue>");
Not sure that this is a good idea for private keys, though.
There's a good tutorial on the subject here

Categories