How to encrypt for OpenPGP keys using C#? - c#

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
.

Related

Using a pre-existing private key to sign file to create a certificate (C#)

I have read round all the articles on StackOverflow and while a lot of them come close to the solution I want, none appear to work.
I simply want to take an existing private key to create a signature of a piece of data. This then becomes part of a data file which includes a header describing the parameters used. Next comes the signed version of a datafile, lastly the datafile itself (a hex file). Concatentation of files is not the issue, generating a certificate using the private and public key pairs I have is. The keys are of the format ("-----BEGIN PRIVATE KEY-----") I can generate signature files easily enough from scratch, but the software that will read the final file is expecting a 256 bye signature, whereas mine (using RSA-256) is only producing 32 byte signatures. It only has access to the public key for decryption and validation of the file signature.
I have come up across a number of errors such as keysets not being valid, not existing, the ComputeHash function not working and causing a crash. I suspect I need to provide more information to my RSACryptographicService through CSPParameters but am not sure what is necessary and sufficient to do so.
I would like to avoid digging into the mathematics behind the algorithm such as manually setting/reading the modulus / P/Q values etc. Can anyone propose a simple way to do this or tell me where I am going wrong? Code is available on request.
The comments you are getting saying 256-byte signature is too long are absurd. Ignore those.
256 bit (32 bytes) would be a very small signature, that cannot be correct. I believe what you're actually looking for is 2048-bit (256-byte) RSA signatures. Those are more sensible by today's standards (though a step larger doesn't hurt).
In terms of importing your key, and not setting key components manually, you should look into "PEM" format RSA keys. There are several nuget packages out there to handle them. Otherwise you can strip the header/footer and decode the base64 yourself and import the key components with some of the built in X509 classes.
.NET does not natively support PEM format keys, and as such, I recommend using a reputable crypto library such as BouncyCastle, as they support PEM key parsing in their RSA algorithms.
This existing stackoverflow link describes how to import keys in BouncyCastle:
Reading PEM RSA Public Key Only using Bouncy Castle

Is it possible to generate Multi-Prime RSA in .NET?

I have some question about implementation Multi-Prime RSA (More than 2 prime) in .NET
Is it possible to generate RSA key with Multi-Prime enabled using RSACryptoServiceProvider()?
Just reading [this article]:http://www.codeproject.com/Articles/10877/Public-Key-RSA-Encryption-in-C-NET but it use a standard RSA with 2 prime.
If I want to do Multi-Prime what should I do?
Thank you
I haven't seen any example of multi prime RSA in C#. The main place to look is of course key pair generation, if you cannot perform multi-prime generation then you cannot use multi-prime RSA. I've checked this on Bouncy Castle as well, and I don't see any RSA-MP key pair generation parameters.
So you either have to find an external library or you have to program it yourself. Note that RSA-MP is not standardized by NIST or specified in a universally recognized standard (such as RFC, PKCS#1) so that's a pretty good reason not to adopt it. Many runtimes only contain well recognized algorithms + a set of older algorithms, using NIST/FIPS as starting point.

Library or tool for implementing reversible encryption [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Simple 2 way encryption for C#
I want to encrypt data in my C# program, but want to be able to decrypt it later. Does anyone know of any library or tool that I can download that will enable me to do that?
Take a look at the System.Security.Cryptography namespace. There's, for example, the TripleDESCryptoServiceProvider.
You can use Microsoft Enterprise Library there is an encryption block in it
If you take a look at the System.Security.Cryptography namespace in the documentation then you'll find classes for most of the common cryptographic systems.
There are two types of algorithm:
Public key (e.g. RSA) - you encrypt with a public key and then decrypt with a private key.
Symmetric key (e.g. AES, DES) - encryption and decryption is performed with the same key.
Which one to choose depends mainly on your situation. Symmetric key algorithms are typically used for encrypting data because they're faster, but that poses the problem of exchanging the key securely. If you can manually configure the endpoints of communication with the same key, then great. If not then you can either use public key to encrypt everything or - as is used in SSL, etc. - add in a handshake phase where the keys are exchanged via public key cryptography.
There is a built in class for Cryptography
System.Security.Cryptography.RSACryptoServiceProvider
Please check this link RSACryptoServiceProvider

Encrypt string in C# and decrypt it in Delphi

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.

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