PGP Service for .NET Allowing Arbitrary Keys - c#

I am in need of a PGP service for .NET that will provide the following:
Encryption/decryption of files provided as byte arrays and/or streams (e.g. writing to hard drive and having the service read it is unacceptable)
Use of arbitrary keys passed in as byte arrays and/or streams
Needs to work for a headless service running on a server with nobody watching it (no modal popups or user input required)
We've felt out a couple of products but not been totally pleased with how any of them worked. Are there any suggestions? Thanks!

It's hard to guess what you could try as there are not much OpenPGP implementations for .NET. Namely, OpenPGPBlackbox package of our SecureBlackbox product is the only comprehensive self-contained implementation for .NET (BouncyCastle offers something as well, but they seem to be limited to older RFC 2440). You are welcome to check OpenPGPBlackbox and if you have problems with it, contact our technical support as described on product pages.

Related

Best ways to store sensitive data

I am trying to find the safest and best way to save and read a password or sensitive data for use in a Selenium test automation written in C#.
Requirements :
Password is not allowed to be visible in the code or any file by only opening it.
Co workers should be able to use it without putting too much work into making it run (KeePass would work, as the users need 2 files (key and key-database) to read the password).
We use Bitbucket to upload the solutions or branches. Bitbucket runs all the code, even the tests without the need of Visual Studio (SonarQube and so on). We can upload the .key files (for example from KeePass) to decrypt the passwords.
Methods I found :
Encryption and Decryption: Id say it's the most common method. This isn't something the company wants to use, as it's too easy to decrypt a ciphertext when encryption method is known.
Environment Variables: Seems to be safe. The sensitive data is stored in the Windows environment variables and you can use it only locally. The problem is co-workers need to add the variables in Windows and we use Bitbucket to upload our solutions onto the server in which we can start the automation tests without using Visual Studio. Not sure if this would be possible.
KeePass: Seems to be the safest way. The user needs 2 files (Database.key and Database.kdbx) to access the passwords. But there's only one question which could help me to set up KeePass in C#. But there are Nuget packages in Visual Studio for KeePass.
Cryptography (symmetric algorithms): A Microsoft video about different kinds of cryptography in .NET core mentioned the symmetric algorithm which seems to work similar to KeePass. To decrypt ciphertext the users need a secret key. Not sure if I can use this.
Im using KeePass which works great for my Selenium tests. The Nuget package to read data from KeePass in .NET6 is: Nuget KPCLib.
This was the easiest and fastest way how to store and read sensitive data without a cloud service.
Take a look at ProtectedData class, which is a wrapper around Windows DPAPI (Data Protection API). It can be used to encrypt data per Windows user1, so other users can't decrypt it.
Obviously, if somebody can log-in as the same Windows user (who encrypted the data through DPAPI), they can decrypt the data by just asking DPAPI to do it for them. But if you trust the Windows user and he/she is not breached (at which point you probably have bigger problems), this should be a decent solution for testing.
EDIT: I'm not sure how this would work under bitbucket. I'll leave the answer here in case somebody finds it helpful...
1 DataProtectionScope.CurrentUser

A way to make a file decryptable only by specific program?

My situation is as follows:
I have to deploy a series of .NET desktop applications consisting of a file with encrypted data and an executable that will access that data and decrypt some parts of it in runtime.
What I need to achieve is that each data container should only be decryptable by that specific .exe it is provided with.
The first idea was to encrypt the data using, say, the hash value of the .exe file as a symmetric key and during decryption calculate the hash value of the .exe file in runtime and decrypt the parts of the data container with it.
However, the problem with that approach is that the user can easily look into the .NET assembly with ILSpy or any other decompiler and discover the whole encryption algorithm which will enable the user to decrypt all the data containers in my series of applications.
Another solution that comes to my mind is to make a small C native library (that is less easy to decomplile) that will perform some manipulations with the .exe assembly information and generate a key for decryption based on it (let's consider the user lazy enough so that he will not try to intercept the key from the memory).
But ideally I wouldn't like to resort to any languages other than C# because porting the application to other platforms with Mono will require additional effort (P/Invokes and so).
So my question is: is there a way I can encrypt the data so that only a certain application would be able to decrypt it?
Of course I understand that in case of a local application it is impossible to keep the data absolutely secure but I need to make the 'hacking' at least not worth the effort. Are there any reasonable solutions or I will have to stick to one of my ideas I described above?
Thank you in advance!
The simple answer is no.
To encrypt and decrypt data, you need an algorithm and, optionally, a secret or key. If a computer can execute the algorithm, someone else can learn what it is. Ignoring decompilation and disassembly, a user could just look at the instructions executed by the CPU and piece together the algorithm.
This leaves the secret. Unfortunately, if the computer or program can access or derive a secret, so can someone with root or administrator rights on that computer for the same reasons above.
However, maybe you are just thinking about the problem the wrong way. If you want the program to access data that no one else can, consider making that data available from a server that users must authenticate to access. Use SSL so data is protected in transit and encrypt the data locally using a key that only the local user and local administrators can access. It is not perfect but it is about the best you are going to get in the general case.
If you need more protection than that, you may want to consider hardware dongles but this gets expensive and complex quite quickly.

Disassembling C#

I've got a question regarding C#.
I am currently working on a medical software product, and one of the important things is to make sure that the patient's data is encrypted. I got two questions regarding this:
1.) How secure is the Microsoft .NET implementation of AES (Rijndael) from System.Security.Cryptography? Does it have any known security flaws, or am I fine just using the MS implementation? (note, I know the basic background of how these algorithms work, but I am not really that deep into it to get an idea of how it works).
2.) Since the data is stored on the same PC as the application, how hard is it to get information from a C# application? Assuming I have somewhere in the code
string encrypPassword = "ThisIsMyPassword";
string encryptedString = EncryptString(ClearString, encrypPassword);
// save encryptedString to harddrive
I know that an attacker could just go down to the assemble code, and at that point there is nothing at all I can do against this (the system has to be able to encrypt / decrypt the data), but is there like a shortcut for C# to get the encrypPassword, since it is managed, or does something like this still require you to go down to the assemble code?
If you have a fixed password compiled into your app, then you don't need to care about the security of AES and known security faults because your data is simply not secure. A sufficiently knowledgable person with access to the PC will be able to decrypt all the data.
And locating a fixed password usually doesn't require any programming knowledge. A good hex editor will do in most case. You don't even need to know what programming language was used.
If your data is used by a single user, then you can tie the password for the patient data to his or her Windows password (or account). Windows provides some specific functions for that. See http://msdn.microsoft.com/en-us/library/aa302402.aspx for how to access it from .NET.
In answer to the first part of your original question - the native Windows implementation of AES is NIST certified to be FIPS 140-2 compliant. Access to the certified implementation is limited to:
Using the Windows Crypto API
Using the CAPICOM com wrapper to the Windows Crypto API
Using the .Net AesCryptoServiceProvider class in the System.Security.Cryptography namespace (this class did not become available until .Net Framework 3.5)
That being said, the implementation in the RijndaelManaged class is the same, it just has not been thru the NIST certification process (this process is very long and very expensive).
The Aes algorithm is very secure (military grade encryption - especially the 256 bit key variant).
The biggest concern (agreeing with the posters above) is keeping your encryption password embedded in the application in plain text.
To store your password data you could use SecureString class from System.Security namespace.
Most decent obfuscators will encrypt the strings from your code before storing them in the assembly's strings section, and inject a method to decrypt them before use. These techniques have also long since been reverse engineered by disassemblers.
Realistically, there is almost no way to really safely store a string in any programming language. Someone can pretty much always either find the string, or reverse engineer your logic used to build it. The best thing you can do is stow down the attacker long enough to make it not worth their time and effort.
In your case, I would probably store the password encrypted in the app (as in, encrypt it yourself manually outside your app, and copy/paste it in). Possibly split it into parts so it isn't stored as a single string. Then put it back together and unencrypt it at runtime, then at runtime store it in a SecureString. Also invest in a good obfuscator, as it will help mask your unencryption logic (which will become the weak link in the security).

How to write a "truly" private method in C#?

In fact, private methods are implemented in C# that can still be searched with Reflection.
What I am going to do is to write public string Encrypt(string data) and private string Decrypt(string cipher) methods to perform encryption and decryption.
Unfortunately, if someone knows .NET framework, he can use Reflection to find Decrypt methods and it decrypt everything that is encrypted.
It seems that is not that secure. So I want to make Decrypt method to truly private method.
But how to do that?
Updated 09 Jan 2012 10:52PM Sydney Time
bdares provides the technical explanation of this question
Eric Lippert provides the political explanation of this question
Thanks both experts!
You can't. If the attacker has access to your code, compiled or source, he can trace your program and find where it's being encrypted or decrypted.
You can add a layer of security by storing the key in a separate location, but generally if the attacker is executing code on your server, you're already screwed.
(You're only worried about this if the attacker is executing code on your server, because otherwise it doesn't matter whether or not the method is private. Also, he can't use reflection to find method names unless he's executing code on your server. In short: you're worrying about the wrong thing here.)
Your fundamental problem is that you've got the trust model wrong. If someone can use reflection then they are the user. You are the software provider. You work for them. Trust flows from them, not from you. They are the person who has to trust you, not you them.
If you don't trust the user then do not sell them your software in the first place. Don't sell weapons to people who you believe plan to attack you.
I believe you are referring to obfuscation, which is an attempt to hide/disguise code from being read by humans when opened in program such as Reflector.
Supplied within Visual Studio is a community use license for PreEmptive Solutions dotfuscator which will provide this functionality on small projects, and also for Windows Phone projects (if you download the add-on). There are also commercial platforms available too, from the same vendor and others .
This blog post explains a little more.
If you're creating your own encryption method, you're doing it wrong. People who know way more about encryption than you or I have already come up with excellent methods for encryption, and MS has implemented most of them already.
For good encryption, it's the keys, not the method, that makes encryption secure. Keep the keys safe and the algorithm can (and should) be published for all to see.
If you're trying to distribute both content and keep it encrypted, aka DRM, you're most probably doomed to failure unless you can keep the keys very well hidden in hardware, and even that will only buy you some time -- maybe months, maybe years.
I am not sure about your exact application. But if you are selling a product to a customer who will be doing both the Encryption and Decryption on their own system, then there is no way to keep the encryption secret from them. But you can instead allow them to generate a new Private Key for their own use. In this way each customer's data is 'secure' in regards to other customers; though obviously still not so secure within the same customer's site. In other situations where you control the encrypted content you can also look into creating a private master key to be generated on your side and only allow the customer to have a public key.

Product activation with public key certificate

I need some ideas how to create a activation algorithm. For example i have demo certificate. Providing that the application runs in demo mode. When full version certificate is provided then application runs in full mode.
Is it even possible and how would be a good way creating this system?
One simple was i was thinking would be just have a 2 encrypted strings, now when the decryption is succsessful with the demo public key certificate then the application will run in demo mode and etc..
You could do something like:
Generate public/private key pair
As owner of private key, you can sign those "activation certificates" (called AC from now on)
In your app, with public key, you can check if the sign is correct
As Overbose mentioned -- you can't prevent reverse engineering. In general someone could take functionality and put it in his/hers own app and thus eliminate any possible activation algorithm. So you can only assume (or make) this is hard enough not to be worth the effort (this is the same as for cryptography -- when you make the cost of breaking the message greater then the profit of gaining it you can say it is well secured).
So you could:
Make executable self-verifying (signed by you, self-checking based on hard-coded public key (one thing: you must skip this value when self-checking)).
Do some tricks with pointers (point to the activation function, go to 7th bit and change value of it for something based on value of another pointer; in some weird places change hard-coded values to those based on occurrence of some bits in other places of the code; generally -- make it more difficult to break than by simply changing bits in executable with hex editor)
Try to make some protocol that your server would use to ask questions about the app ("gimme the value of 293 byte of yourself") and check answers.
Use imagination and think of some weird self-checking method nobody used before :)
As mentioned -- none of this is secure from cutting the authentication part off. But nothing is and this could make it harder for crackers.
Background: I've deployed an activation based system built on top of a third-party license system, i.e. server, database, e-commerce integrations. I've also separately written a C# activation system using RSA keys, but never deployed it.
Product Activation commonly means that the software must be activated on a given machine. I assume that's what you mean. If all you want to do is have two strings that mean "demo" and "purchased", then they will be decrypted and distributed within hours (assuming your product is valuable). There is just no point.
So. assuming you want "activation", then when the user purchases your software, the following process needs to happen:
Order-fulfillment software tells Server to generate "Purchase Key" and send to user
User enters "Purchase Key" into software
Software sends Purchase Key and unique Machine ID to server.
Server combines Purchase Key and Machine ID into a string and signs it with its certificate and returns it to user.
Software checks that signature is valid using Servers public key.
Software could check in lots of places: loading the sig in lots of places, checking it in others.
When generating Purchase Keys, the server can store not only what produce was purchased, but what level of product. You can also have "free" products that are time limited, so the user can try the full version of the software for 30 days.
You are using C#, so make sure you obfuscate the binaries, using dotfuscator or equivalent. However, even with that there is nothing you can do against a determined hacker. Your goal, I assume, is to force non-paying users to either be hackers themselves, or to have to risk using a cracked version: kids wont care, corporations might. YMMV.
The code that does the checking needs to be in every assembly that needs protecting, otherwise an attacker can trivially remove protection by replacing the assembly that does the checking. Cut and paste the code if you have to.
Or just buy something.
Another option is to have the server pre-generate "Purchase Keys" and give them to the Order fulfillment service, but then you dont get to link the key to the customers details (at least not until they register). Better to have the ecommerce server hit your server when a purchase has been made, and have your server send it out.
The hard part isn't so much the generation of activation keys as it is the creation of the server, database, and the integration with e-commerce software, and most of all, human issues: do you allow unlimited installs per Purchase Key? Only 1? If only 1 then you have to have customer-support and a way to allow a user to install it on a new machine. That's just one issue. All sorts of fun.
This guy wrote a blog post about a similar idea, explaining what he did with their own commercial software. Also wrote a list of recommendations about the most obvious cracking techniques. Hope it helps.
One simple was i was thinking would be just have a 2 encrypted
strings, now when the decryption is succsessful with the demo public
key certificate then the application will run in demo mode and etc..
Could be a simple solution. But this way you won't prevent someone to reverse engineer your binaries and make the execution jump to the correct line. Everyone has your program, has a complete version of it, so it's only a matter of find how to break this simple mechanism.
Maybe a better solution is encrypt a part of the binaries needed to use the full application version, instead of a simple string. This way to execute the application complete version someone need to decrypt those binaries in order to execute them.
Please take in consideration that even that solution isn't enough. There are other problems with that:
Does all the version of your tool will share the same encryption key? Breaking one of them for breaking all..
Even if you use a different key for each binary application released, does the encrypted binary are identical? Once cracked one, you can reuse the unencrypted binaries for all distributed applications.
How to solve these problems? There's no simple solution. Most of the more important commercial software with even sophisticated protection systems are broken just few hours or days after they have been released.
Product activation is not a problem that asymmetric cryptography can solve. Asymmetric cryptography is about keeping secrets from your adversary. The problem is that you can't keep a secret that is stored on you're adversaries machine, that would be security though obscurity.
The correct way to do product activation. Is to generate a Cryptographic Nonce that is stored in a database on your server. You give this Nonce to the customer when they buy the product, and then they activate it online. This activation process could download new material, which would make it more difficult for the attacker to modify the copy they have to "unlock" new features.
But even with DRM systems that require you to be online while using the product. Like the ones found in new games like "From Dust" are still broken within hours of their release.
One of the benefits of public key encryption is that you can verify the origin of a given piece of data. So if you store the public key in your assembly, then sign a given piece of data (say an authorization code or serial number) your assembly can verifiably determine that you were the one that created that data - and not a hacker. The actual data itself isn't all that important - it can be a simple pass/fail value.
This is actually pretty easy to do with .NET. You can use an x509 certificates or like we use in DeployLX Licensing the RSACryptoServiceProvider.
I would highly recommend buying a commercial product (doesn't really matter which one, though DeployLX is excellent) and not doing this yourself for 2 reasons
Even if you're a great developer, you'll probably get it wrong the first time. And any savings you might have enjoyed by rolling your own will be lost to recovering from that mistake.
You'll spend far more time working on your own system - time that you should spend making your product great.
The second phase in protecting the software is to make sure that it runs the way you created it - and hasn't been modified by a hacker. It really doesn't matter what encryption you use if hackers can check if( licensed ) to if( true ).
You can use AsProtect to solve this problem. This is good staring point.

Categories

Resources