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
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
.
Preamble
I was digging deep into the .Net x509certificate2 and x509certificate objects noticed that both the certificate classes serialize the private key to disk by default due to the verifiable use of Persist-Key options in the constructors of the x509certificate2 and x509certificate classes using a default option set for CspProviderFlags that does not include CspProviderFlags.CreateEphemeralKey. This is verifiable via any number of web sites that show the source for .Net as well as with a copy of resharper should you choose to do it yourself.
Looking further, In fact these .Net objects simply seem to be wrappers for a central old style crypto32.dll cryptographic context. What worries me about this is that looking at the code deeper I find that it seems to explicitly look in an on-disk file storage for public and private keys in the getters and setters for the PublicKey field on the x509certificate2 and x509certificate object.. despite the fact that I would otherwise expect them to only exist in memory. Based on this knowledge it seems to store my private key in this storage even if I do not want it to do so, because the constructor does not allow you to change this option and turn it off based on the constructor list I am seeing when I look at the documentation; So if you set() or get() from the PrivateKey field it is really just collecting it from this file store behind the scenes.
Reason for my question
I think that being forced to leak my private key to the file system - even temporally - is a huge security issue so I do not want to do it. I also do not trust the certificate store. Even if you disagree with me, I personally believe that being forced to serialize my private key to disk even if I do not intend to do so is a huge security issue, so I do not want to do it.
Goal
My current goal is to simply be able to generate RSA public and private X509 keys in C# that can be used on windows without needing to be forced to write them to the hard disk as part of the creation process, and I am not finding many valid options as all of the ones I can find seem to have either hidden gaps or publicly known issues.
The goal is not to never write them to disk, it is just to not do so unless its with code I have written and know to be secure to make sure they are fully encrypted at rest; ie, it should not do so unless I explicitly ask for it after the keys themselves have been fully encrypted.
Goal tldr;
In short: I want to write secure software on windows using C# to generate a 509 certificate that doesn't force me to export, import, or otherwise leak my private key to the file system as part of the certificate creation. I want to be able to create my own X509Certificates on windows using as little third party code as possible.
Options I have considered
The Standard .Net types as stated have been looked at in depth and found to be lacking due to the above issues. I just don't have enough access to the internal CSP settings as the constructors and access do not expose them, and the defaults used as what I would personally consider to be insecure.
The Bouncy Castle library looked like a good option at first, but it actively exposes my public and private keys to the file system just lie the normal .net types do when it converts them to the standard .Net types since these objects store things behind the scenes without asking BC if its ok first..
I attempted to find a crypto32.dll p-invoke option that would allow me to not serialize my keys, only to find that all I could find did exactly that even when I did not want them to. And finding data on it was very difficult so I mostly just looked at the source code only to find that it didn't seem to like me trying to not store keys.
I am unable to find any other options despite spending several days researching this topic. Even Stack Overflow says to use BC or the native typesd in most cases; yet that doesn't solve my problem.
Question
How would I best create my own X509 Certificates without doing any of the following as I feel they are all security issues:
The use of makecert.exe requires I allow my process execute rights on the server so it can start a process; thats a security issue waiting to happen. Not to mention, I cant audit the code and I am willing to bet its still storing the keys in the cert store even If I do not want them to be.
The use of the C#/.Net x509certificate2 and x509certificate objects serialize a generated public key to disk by default via its calls to the Certificate Store so that's not an option; The goal is to do things in a secure manner, and so the idea of all the private keys I'm generating being stored on disk for just anybody to access them doesn't leave me with good feelings. ANd its very hard to find data on the cert store; thus I cant validate its security and have to consider it not a valid option.
The use of third party libs such as Bouncy Castle creates update scenarios and the possibility of a third party that has to be trusted, creating an even larger attack surface; and sadly they all use the same conversions that are affected by what I am personally calling the "hidden private key store" issue of them trying to play nice with the standard System.Security.Cryptography API by using the same objects that have this leaking key issue. So If in general we want to keep the system as secure as possible.. that sort of leak is not an option.
Without going super-low-level (or disabling paging altogether) you can't guarantee that your private key material is never written to disk, because it can always be paged out. Even then, on a system that supports hibernation your key will be present in the hibernation file.
The crypt32 key storage mechanism uses DPAPI (user or machine scoped, depending on your import flags and/or flags in the PFX) to encrypt the key material at rest. So while it is involving the filesystem, it isn't "stored on disk for just anybody to access them"; unless they're running as you, or have permission to access the system keys.
Like others have said, if you are this concerned and not willing to trust anyone/any outside APIs then you are going to have to use a lower level language than .Net. .Net is a great RAD type language, but if you don't trust the machine you are running on, you will want the lowest level environment you can achieve.
C would be a good option.
which algorithm is better for encrypt and decrypt data inside a project?
i designed and developed a site like below :
htttp://www.soscharge.com
this site is about mobile charge codes ...
i want to encrypt mobile charge codes during insert to database and decrypt them for showing to users...
hash algorithm is not a good idea about this purpose (one way algorithm)
i heard something about symmetric and asymmetric algorithms (but i want to learn how can i write a simple and powerfull algorithm by myself)
thanks in advance
never - NEVER write your encryption-algorithms yourself if you are not an expert and get paid for it! Seriously: you will never get a good and secure algorithm working just by yourself. Use the tools in the Framework - System.Security.Cryptography namespace! And you don't ask for synchronous vs. asynchronous but I guess you are thinking on symmetric vs. assymetric algorithms
now to the answer:
as you have full controll of your database and an outsider should not be able to get to it you can use symmetric key algorithms because you protect your "secret" (the key) on your system and the user will never see it (or so it should be - if your system is secure can only a IT-guy tell you)
which algorithm is better for encrypt and decrypt data inside a project?
You didn't give us any criteria on which to evaluate "better."
Frankly, it sounds like you're not a security expert. This stuff is so easy to get wrong, even if you pick the "best" algorithm (look at the recent RSA debacle). If you have secrets that truly need to be safeguarded, you should hire a security expert. Your stakeholders will thank you later.
(but i want to learn how can i write a simple and powerfull algorithm by myself)
Take a course. Read a book (or two; the Bruce Schneier books are decent). Practice for about 10,000 hours.
i heard something about synchronous and asynchronous algorithms
Symmetric and asymmetric, perhaps? I mean, this tells us all we need to know about your level of expertise on this subject.
Seriously, don't do this yourself. Get an expert to help you.
I assume that you need symmetric algo, by now best choice is AES. It's easy, strong and has implementations for most platforms and languages.
I've seen a ton of questions asked about Blowfish and C# and the usual answer is BouncyCastle. However, the project has basically no documentation and I can't find my way around the directory structure to even find unit tests as examples. I mean, is Blowfish known as Asn1, Bcpg, Crypto(in general?), EC, Ocsp, Pkcs, or what? I lack the domain knowledge of knowing what all of the acronyms in the source code means.
Is there any useful articles or blogs or something that has succeeded in using the C# BouncyCastle API for Blowfish? My primary need is to use Blowfish for password hashing.
For password hashing I would recommend going with bcrypt which internally uses Blowfish. The advantage of using bcrypt is that you can easily configure how expensive it is in generating your output hash. This is important as the biggest problem with many popular hash algorithms is that they work very quickly and this allows a brute force attack to run through many permutations to find a match. By specifying a large work factor you can make it slow to run (in computer terms but still fast in human terms) and so a brute force attack becomes unfeasable.
There are C# implementations already available.
Also you should check out: Why does BCrypt.net GenerateSalt(31) return straight away?
And the codeplex implementation: bcrypt.codeplex.com
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