I have been looking for a simple encryption/decryption class for storing information in the database. Trouble is I have no clue what I'm looking at half the time, so I really don't know if what I find is really all that worth implementing for what I need, whether it be over-complex or too easy to crack.
I have brain stormed about it for a bit, my first thought-train leading to a simple "switch, add, multiply" key for the ACII Values, but I think that wouldn't really be worth it after seeing what encryption classes actually are.
Essentially I'm looking for a key that encrypts any and all data (including table and column names) on storage, and decrypts on withdrawal. But like I said, doesn't need to be too complex, but if someone does want to access the data, they have to earn it haha.
Can anyone suggest a good link/provide a simple class for what I'm looking for? It could possibly be something I have found before, but like I said, I haven't the faintest as to what I'm looking at half the time
Thanks in advance!
Pre-emptive Edit I know some Databases have their own encrypt/decrypt methods, but I figure this is the easiest way to implement it because I will be working will multiple different database programs.
AES 256 is (while potentially overkill) a very secure encryption algorithm. Microsoft provides an implementation in System.Security.Cryptography and the example at MSDN is a great place to get started.
I've used this for database encryption and it works just fine.
Since you said you are new to encryption, I will try to touch on what encryption does, and doesn't do for you. Encryption takes normal data (ie. ("My private string")) and turns it into random data (bunch of bytes), only reversible by knowing the private key (in AES 256). Data, since it is different between cells, and likely private/important information is a good thing to encrypt.
Your database schema is constant, so encryption is only minimally useful here. The difference between calling a table "Names" and "A" and "oiaeoriuojdklfjsad" (this last is an example "encryption") is minimal. This is what is meant by "security by obfuscation". You could argue that choosing a random name is slightly more secure than a descriptive one, but it is really just going to confuse you when you try to use it, and the real "gold" a hacker will want is the data anyways. Knowing what kind of data it is isn't really going to help if it's going up against a good encryption algorithm.
Related
I'm working on an encryption class that is using Rijndael algorithm (C#, ASP.Net 4.5), and out of curiosity I was wondering how beneficial would it be to encrypt the string twice. I mean Encrypt the string with a key and then Encrypt the resulting encryption with another key?
Does this make it that much more secure (I know nothing is ever secure and there could be other holes in my software that could be used to exploit)? Is it worth the CPU overhead (not sure how heavy this is but I can't imagine it would light)?
I was looking for some suggestions online but was not able to find any. Any thoughts?
Have a couple of questions that may be of use to you:
Is there any benefit to encrypting twice using pgp?
Is encrypting twice good or bad?
https://crypto.stackexchange.com/questions/779/hashing-or-encrypting-twice-to-increase-security
https://crypto.stackexchange.com/questions/5382/is-it-safer-to-encrypt-twice-with-rsa
https://crypto.stackexchange.com/questions/2314/does-encrypting-twice-using-the-same-block-cipher-produce-a-security-weakness
General idea seems to be this point:
Well, think about it this way. If breaking one encryption with brute
force will take longer than the lifetime of the universe, are you any
safer with an encryption scheme that will take twice the lifetime of
the universe? No. The first encryption cannot be broken. Adding a
second encryption just adds computation overhead with no real benefit. - mikeazo
I would advise asking this question in https://crypto.stackexchange.com/, they may give you more detailed information on the topic.
There's a simple rule in cryptography. All the security should be in the key. Based on that there should be no additional security in encrypting twice because all your security should be in the choice and storage of your key.
Now that being said... you could get some additional security if you make wrong choices. For example say you encrypt the first time with ECB mode (Electronic Code book), because of the way that mode works (by encrypting each block of your plaintext separately), you could get extra security by encrypting a second time in a more secure mode (CBC or CTR). But... you could just as well encrypt in CBC mode the first time around.
You could encrypt the first time with an insecure algorithm (such as DES) and encrypt a second time with a much better algorithm (such as AES).
But these situations are hypothetical and would require you to intentionally make mistakes or be extremely negligent. If you use AES (Rijandael) twice in a secure mode like CTR or CBC then you will not get any additional security from encrypting twice so long as your key is stored securly and selected in a secure manner.
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.
I am writing a .net application and want to use a supper strong encryption key by using the unicode characters to make it hard for the hackers to hack the code. The encryption key would be any characters from the http://www.unicode.org.
For example my encryption key could லูᇉޒۻڃxxxxxxxxxxxx + couple hundred characters which is very difficult for the computer to predict my code. I think the unicode has more than 95,000 characters.
I am wondering if there is any data corruption because of these complex characters. Of course I have to check the decrypt data to make sure the code can decrypt before I save the information to the database. I have tested my code for more than 10 millions times to see how reliable and it run pretty good.
Any thoughts guys?
Encryption is very very difficult to do. More likely than not, your approach will be very insecure.
The strength of an algorithm is more than just a key size. I'd wager that DES with a 56-bit key is more "secure" than probably any home made cipher.
The AES process was a multiple year effort of every cryptographer in the world, multiple government agencies, support from Microsoft, RSA (among others), various open source projects, and millions of dollars. Even after all that, we still find new attacks against AES.
What are your requirements? You should use established protocols and algorims. If you say what your trying to do, we can give better advice.
I'm not asking for a tutorial with code, I'm trying to do the research, but I want to make sure I'm asking the right questions.
What's the best form of encryption I can use out of the box with .NET?
Public/Private key, where do I store these things securely?
What tools should I have in order to do this properly?
I started off with an AESCryptoServiceProvider, encrypted a string I passed in, I was happy. Tested that if I called it twice it would come out with the same value. Then realized I hadn't provided any form of key, so a second run of the app yielded different results. So I began reading up, seeing RSA Public/Private keys etc. etc. And just want make sure I'm going down the right path with the reading I'm doing. There's tons of examples out there, few mention where you put these keys or where you even get them from.
There's a lot of cryptological functions in System.Security.Cryptography.
They have hashes, crypts, streams, and a lot more.
The RSA provider is a good one. And about storing the constants securely. I can only suggest storing them crypted in the solution.
You shouldn't be able to read them from the source, so there needs to be some kind of security after the assembly has build. Maybe obfuscation, maybe something else.
About the generating of the key, do not use your own system, or any development system I guess.
EDIT:
To generate keys you better use either user input, for example, just create a little application, that calculated the time it takes to type a certain piece of text, per letter.
Or use a HRNG/TRNG, Hardware Random Number Generator (uses input from the actual world, retrieved through sensors). Or True Random Number Generator, basically also HRNG, but mostly with other forms of input, very advanced.
RANDOM.ORG should be able to help you out.
If it's not that extreme important, just go smack your head against your keyboard, and see the results :).
Go for AES. Stack Overflow already has a wonderful implementation of AES Algorithm as an answer.
Regarding "Public/Private key, where do I store these things securely?", I recommend that you do not re-invent the wheel. Microsoft has already spent a great deal of effort to build, and is actively maintaining and (hopefully) improving, infrastructure to store private keys: https://msdn.microsoft.com/en-us/library/windows/desktop/bb204778%28v=vs.85%29.aspx. You can use the native key storage.
So, to start off, I want to point out that I know that these things are never fool-proof and if enough effort is applied anything can be broken.
But: Say I hand a piece of software to someone (that I have written) and get them to run it. I want to verify the result that they get. I was thinking of using some sort of encryption/hash that I can use to verify that they've run it and obtained a satisfactory result.
I also don't want the result to be "fakeable" (though again, I know that if enough effort to break it is applied etc etc...). This means therefore, that if I use a hash, I can't just have a hash for "yes" and a hash for "no" (as this means the hash is going to be only one of 2 options - easily fakeable).
I want the user of the tool to hand something back to me (in possibly an email for example), something as small as possible (so for example, I don't want to be trawling through lines and lines of logs).
How would you go about implementing this? I possibly haven't explained things the greatest, but hopefully you get the gist of what I want to do.
If anyone has implemented this sort of thing before, any pointers would be much appreciated.
This question is more about "how to implement" rather than specifically asking about code, so if I've missed an important tag please feel free to edit!
I think what you're looking for is non-repudiation. You're right, a hash won't suffice here - you'd have to look into some kind of encryption and digital signature on the "work done", probably PKI. This is a pretty wide field, I'd say you'll need both authentication and integrity verification (e.g. Piskvor did that, and he did it this way at that time).
To take a bird's eye view, the main flow would be something like this:
On user's computer:
run process
get result, add timestamp etc.
encrypt, using your public key
sign, using the user's private key (you may need some way to identify the user here - passphrases, smart cards, biometrics, ...)
send to your server
On your server:
verify signature using the user's public key
decrypt using your private key
process as needed
Of course, this gets you into the complicated and wonderful world that is Public Key Infrastructure; but done correctly, you'll have a rather good assurance that the events actually happened the way your logs show.
I'm pasting in one of your comments here, because it goes to the heart of the matter:
Hi Eric. I should have pointed out
that the tool isn't going out
publically, it will go to a select
list of trusted users. The tool being
disassembled isn't an issue. I'm not
really bothered about encryption, all
I need to do is be able to verify that
they ran a specific process and got a
legitimate result. The tool verifies
stuff, so I don't want them to just
assume that something works fine and
not run the tool.
So basically, the threat we're protecting against is lazy users, who will fail to run the process and simply say "Yes Andy, I ran it!". This isn't too hard to solve, because it means we don't need a cryptographically unbreakable system (which is lucky, because that isn't possible in this case, anyway!) - all we need is a system where breaking it is more effort for the user than just following the rules and running the process.
The easiest way to do this is to take a couple of items that aren't constant and are easy for you to verify, and hash them. For example, your response message could be:
System Date / Time
Hostname
Username
Test Result
HASH(System Date / Time | Hostname | Username | Test Result)
Again, this isn't cryptographically secure - anyone who knows the algorithm can fake the answer - but as long as doing so is more trouble than actually running the process, you should be fine. The inclusion of the system date/time protects against a naive replay attack (just sending the same answer as last time), which should be enough.
How about you take the output of your program (either "yes" or "no"?), and concatenate it with a random number, then include the hash of that string?
So you end up with the user sending you something like:
YES-3456234
b23603f87c54800bef63746c34aa9195
This means there will be plenty of unique hashes, despite only two possible outputs.
Then you can verify that md5("YES-3456234") == "b23603f87c54800bef63746c34aa9195".
If the user is not technical enough to figure out how to generate an md5 hash, this should be enough.
A slightly better solution would be concatenate another (hard-coded, "secret") salt in order to generate the hash, but leave this salt out of the output.
Now you have:
YES-3456234
01428dd9267d485e8f5440ab5d6b75bd
And you can verify that
md5("YES-3456234" + "secretsalt") == "01428dd9267d485e8f5440ab5d6b75bd"
This means that even if the user is clever enough to generate his own md5 hash, he can't fake the output without knowing the secret salt as well.
Of course, if he is clever enough, he can extract the salt from your program.
If something more bullet-proof is needed, then you're looking at proper cryptographic signature generation, and I'll just refer you to Piskvor's answer, since I have nothing useful to add to that :)
In theory this is possible by using some sort of private salt and a hashing algorithm, basically a digital signature. The program has a private salt that it adds to the input before hashing. Private means the user does not have access to it, you however do know the salt.
The user sends you his result and the signature generated by the program. So you can now confirm the result by checking if hash(result + private_salt) == signature. If it is not, the result is forged.
In practice this is almost impossible, because you cannot hide the salt from the user. It's basically the same problem that is discussed in this question: How do you hide secret keys in code?
You could make the application a web app to which they have no source code access or access to the server on which it runs. Then your application can log its activity, and you can trust those logs.
Once a user has an executable program in their hands, then anything can be faked.
It's worth noting that you aren't really looking for encryption.
The "non-repudiation" answer is almost on the money, but all you really need to guarantee where your message has come from is to securely sign the message. It doesn't matter if someone can intercept and read your message, as long as they can't tamper with it without you knowing.
I've implemented something similar before information was sent plaintext - because it wasn't confidential - but an obfuscated signing mechanism meant that we could be (reasonably) confident that the message was generated by our client software.
Note that you can basically never guarantee security if the app is on someone else's hardware - but security is never about "certainty", it's about "confidence" - are you confident enough for your business needs that the message hasn't been tampered with?