How to protect the encryption key from reverse engineering? - security

My software is using AES Rijndael.
I am using a SHA-256 hash to generate a key from a string with an arbitrary length, and then passing this as both the private and public key since in this instance I do not need to differentiate between the two.
How do I protect my key from being hacked out of the executable?
I know not to use a literal but instead generate the key at runtime with some predetermined steps, but all the same the key will still be in memory right before its sent on to the AES initialization function and so can quite easily be retrieved then.
AES is obviously very secure, but what good does that do me if someone breaks the executable instead?
Is there some common practise when solving this problem?

This can't be done. This is the basic problem with e.g. DRM scheme's on PC's: they need to have the key in memory, so it can be extracted. You can maybe obscure it while it is not in use, but that's about it. And if your application is popular and distributed, then somebody will crack you delicious scheme. That's why some companies use dongles or TPM chips for high value applications.

There is something - very complex in mathematical theory - called "whitebox cryptography". In this case, the AES algorithm is modified in a way, that it builds up the secret during encryption. I do not know exactly, how this is achieved, but this one does not need to have a initialized secret, but the secret is part of the algorithm.
An attacker might see, that your AES implementation is a bit "different" but at no time in execution the key is visible in memory. The only chance an attacker will have, is to copy the whole whitebox code but it is really hard to reverse engineer this - he would just be able to use it. Anyway depending on the way you use the AES, this might be enough to break in.

Related

Do I need MD5 as a companion to SHA-1?

Do I need both MD5 and SHA-1 values to be sure the downloaded file is
a) Untouched by hackers. For example, when I need to download some app's .iso via torrents
and
b) Not corrupted during technical issues? For example, some unstable network connection during download.
Or, probably, SHA-1 value will be enough for both checks?
Also, is SHA-1 (without MD5) enough to be sure that some file downloaded years ago and stored somewhere on my HDD haven't degradated?
From a security perspective MD-5 is utterly broken.
SHA-1 is considered suspicious, and avoided for most uses if at all possible. For new projects: don't use it at all.
SHA-2 (aka SHA-256, SHA-512, etc.) is still widely used for fast hashes.
SHA-3 is the future since 2012, nothing is stopping you from using it already. I see little reason not to use it for new projects.
What's the problem with older ones:
Their resistance to finding collisions is below par: This is an attacker creating 2 contents that have the same hash. These are constructed at the same time. This problem is there for MD5 and SHA-1, and it's BAD, but requires the attacker creating both versions (and then they can do a switch at any time they want undetected).
Their resistance to length extension attacks is relatively weak. This is especially true for MD5, but SHA-1 and even SHA-2 to some degree suffer from it.
When is it not a problem: to ensure your disk has not produced an error: and hash will do, even a simple CRC32 will work wonders (and I'd recommend the simpler CRC check), or a RAID array, as these can fix errors, not just detect them.
Use both ?
Well if you have to find a collision on one hash and have that same set of plaintexts also produce a collision on another hash, is probably more difficult. This approach has been used in the past, The original PGP did something like it. If I'm not mistaken it had a number of things it calculated, one of them simply the length (which would prevent the extension attack above).
So yes, it likely adds something, but the way md5 and SHA-1 and SHA-2 work internally is quite similar, and that's the worrisome part: they are too much alike to be sure just how much it adds against a highly sophisticated attacker (think the level of the NSA and their counterparts).
So why not use one of the more modern versions of SHA-2, or even better SHA-3 ? They've no known weaknesses and have been peer-reviewed heavily. As such for any commercial level use, they should be more than enough.
Refs:
https://en.wikipedia.org/wiki/Length_extension_attack
https://en.wikipedia.org/wiki/Collision_attack
https://stackoverflow.com/questions/tagged/sha-3

AES vs Blowfish for file encryption

I want to encrypt a binary file. My goal is that to prevent anyone to read the file who doesn't have the password.
Which is the better solution, AES or Blowfish with the same key length? We can assume that the attacker has great resources (softwares, knowledge, money) for cracking the file.
Probably AES. Blowfish was the direct predecessor to Twofish. Twofish was Bruce Schneier's entry into the competition that produced AES. It was judged as inferior to an entry named Rijndael, which was what became AES.
Interesting aside: at one point in the competition, all the entrants were asked to give their opinion of how the ciphers ranked. It's probably no surprise that each team picked its own entry as the best -- but every other team picked Rijndael as the second best.
That said, there are some basic differences in the basic goals of Blowfish vs. AES that can (arguably) favor Blowfish in terms of absolute security. In particular, Blowfish attempts to make a brute-force (key-exhaustion) attack difficult by making the initial key setup a fairly slow operation. For a normal user, this is of little consequence (it's still less than a millisecond) but if you're trying out millions of keys per second to break it, the difference is quite substantial.
In the end, I don't see that as a major advantage, however. I'd generally recommend AES. My next choices would probably be Serpent, MARS and Twofish in that order. Blowfish would come somewhere after those (though there are a couple of others that I'd probably recommend ahead of Blowfish).
It is a not-often-acknowledged fact that the block size of a block cipher is also an important security consideration (though nowhere near as important as the key size).
Blowfish (and most other block ciphers of the same era, like 3DES and IDEA) have a 64 bit block size, which is considered insufficient for the large file sizes which are common these days (the larger the file, and the smaller the block size, the higher the probability of a repeated block in the ciphertext - and such repeated blocks are extremely useful in cryptanalysis).
AES, on the other hand, has a 128 bit block size. This consideration alone is justification to use AES instead of Blowfish.
In terms of the algorithms themselves I would go with AES, for the simple reason is that it's been accepted by NIST and will be peer reviewed and cryptanalyzed for years. However I would suggest that in practical applications, unless you're storing some file that the government wants to keep secret (in which case the NSA would probably supply you with a better algorithm than both AES and Blowfish), using either of these algorithms won't make too much of a difference. All the security should be in the key, and both of these algorithms are resistant to brute force attacks. Blowfish has only shown to be weak on implementations that don't make use of the full 16 rounds. And while AES is newer, that fact should make you lean more towards BlowFish (if you were only taking age into consideration). Think of it this way, BlowFish has been around since the 90's and nobody (that we know of) has broken it yet....
Here is what I would pose to you... instead of looking at these two algorithms and trying to choose between the algorithm, why don't you look at your key generation scheme. A potential attacker who wants to decrypt your file is not going to sit there and come up with a theoretical set of keys that can be used and then do a brute force attack that can take months. Instead he is going to exploit something else, such as attacking your server hardware, reverse engineering your assembly to see the key, trying to find some config file that has the key in it, or maybe blackmailing your friend to copy a file from your computer. Those are going to be where you are most vulnerable, not the algorithm.
AES.
(I also am assuming you mean twofish not the much older and weaker blowfish)
Both (AES & twofish) are good algorithms. However even if they were equal or twofish was slightly ahead on technical merit I would STILL chose AES.
Why? Publicity. AES is THE standard for government encryption and thus millions of other entities also use it. A talented cryptanalyst simply gets more "bang for the buck" finding a flaw in AES then it does for the much less know and used twofish.
Obscurity provides no protection in encryption. More bodies looking, studying, probing, attacking an algorithm is always better. You want the most "vetted" algorithm possible and right now that is AES. If an algorithm isn't subject to intense and continual scrutiny you should place a lower confidence of it's strength. Sure twofish hasn't been compromised. Is that because of the strength of the cipher or simply because not enough people have taken a close look ..... YET
The algorithm choice probably doesn't matter that much. I'd use AES since it's been better researched. What's much more important is choosing the right operation mode and key derivation function.
You might want to take a look at the TrueCrypt format specification for inspiration if you want fast random access. If you don't need random access than XTS isn't the optimal mode, since it has weaknesses other modes don't. And you might want to add some kind of integrity check(or message authentication code) too.
I know this answer violates the terms of your question, but I think the correct answer to your intent is simply this: use whichever algorithm allows you the longest key length, then make sure you choose a really good key. Minor differences in the performance of most well regarded algorithms (cryptographically and chronologically) are overwhelmed by a few extra bits of a key.
Both algorithms (AES and twofish) are considered very secure. This has been widely covered in other answers.
However, since AES is much widely used now in 2016, it has been specifically hardware-accelerated in several platforms such as ARM and x86. While not significantly faster than twofish before hardware acceleration, AES is now much faster thanks to the dedicated CPU instructions.

new encryption algorithm for ssh

I am asked to add a new algorithm to ssh so data is ciphered in new algorithm, any idea how to add new algorithm to ssh ?
thanks
It is possible to add some new algorithm to SSH communication, and this is done from time to time (eg. AES was added later). But the question is that you need to modify both client and server so that they both support this algorithm, otherwise it makes no sense.
I assume that you were asked to add some custom, either home-made or non-standard algorithm. So first thing I'd like to do is to warn you that the added algorithm can be weak. You need to perform at least basic search for information about this algorithm, as if it's broken, you will do completely useless and even dangerous work.
As for software modification themselves - it's a rare job to do so most likely you won't find anybody with this experience there. However the code that handles various algorithms is typical and adding new algorithm is trivial - you add one source file with algorithm implementation and then modify a bunch of places by adding one more case to switch statement.
In my career I've worked on a private fork of ssh that was sold as closed-source commercial software. Even they in all their crazy stupidity (private fork? who in their right mind uses non-Open Source encryption software? I thought our customers were completely off their rockers.) didn't add a new encryption algorithm.
It can be done though. Adding the hooks to the ssh protocol to support it isn't hard. The protocol is designed to be extensible in that way. At the beginning the client and server exchange lists of encryption algorithms they're willing to use.
This means, of course, that only a modified client and modified server will talk to eachother.
The real difficulty is OpenSSL. ssh does not use TLS/SSL, but it does use the OpenSSL encryption library. You would have to add the new algorithm to that library, and that library is a terrible beast.
Though, I suppose you could add the algorithm without adding it to OpenSSL. That might be tricky though since I think openssh may rely heavily on the way the OpenSSL APIs work. And part of how they work allows you to pass around a constant representing which algorithm you want to use and then a standard set of calls for encryption and decryption that use the constant to decide on the algorithm.
Again though, if I recall correctly, OpenSSL has an API specifically for adding new algorithms to its suite. So that may not be so hard. You will have to make sure this happens when the OpenSSL library is being initialized.
Anyway, this is a fairly vague answer, but maybe it will point you in the right direction. You should make whoever is doing this pay enormous sums of money. Stupidity that requires this level of knowledge to pull off should never come cheaply.

.NET 3.5 - Hashing a password using System.Cryptography

I am a bit of a newbie around Security nitty gritties and especially around Cryptography.
In the application we are building(ASP.net application built on .NET 3.5), we are currently using Databases to save our users authentication information (AD etc is not an option at this point).
The intention is to do a one way salted hash of the passwords using SHA256Managed on user creation and then validate the users using the same.
Ideally, we do not want to use any third party dll's for the hashing algorithm unless absolutely necessary to avoid any unnecessary dependencies.
Questions:-
1. Is there a better option than doing a salted one way hash?
2. Is SHA256 a reasonably reliable / secure option or should we be considering anything else?
3. Is the SHA256Managed implementation in System.Cryptography good enough in terms of it speed etc or should we be considering 3rd party alternatives to it?
Any pointers as to the approach / implementation will be helpful.
I did some research on this back in the day, and the consensus was BCrypt was one of the best ways to do a one way hash.
You can see a C# implementation here: http://derekslager.com/blog/posts/2007/10/bcrypt-dotnet-strong-password-hashing-for-dotnet-and-mono.ashx
In addition, what's nice about BCrypt is you can decide how many rounds you'd like it to go through.
So, you can make it take about 1 second to encrypt for example. For a user, that's an acceptable wait time, but for someone trying to attack you through brute force, 1 second is an eternity.
I am no security expert, so take what I say here as a grain of salt. A salt you can send in to your BCrypt method :)
In addition, here's some advice from Atwood on this: http://www.codinghorror.com/blog/2007/09/youre-probably-storing-passwords-incorrectly.html
Update:
Since answering this, NuGet has made using BCrypt much easier: http://nuget.org/packages?q=bcrypt
I can't vouch for any particular implementation there, so take a look at the code, but this should make using and integrating BCrypt much easier.
Yes, retina scan (just kidding). Storing passwords as hashes with salt is the correct way.
SHA256 is good. Obviously I don't know the type of an application you are working on, but SHA256 is good for the vast majority of projects. You can always go to a higher key length (384, 512) if required. Consult with your security architect.
SHA256Managed (we are talking .net, right?) is good. We use it in our projects.
Please also consider reading this:
http://www.obviex.com/samples/hash.aspx
Yes, there's nothing wrong with SHA256 and certainly SHA256Managed will be "fast enough" for most use cases (I'm sure you're not expecting to be validating 1000s of login requests per second, and even if you were, the rest of the site would still be dwarfing the login requests...)
But have you considered the Membership stuff that's built-in to the framework? They're already done all the hard work in terms of securely storing credentials, and implementing all the support functionality as well (such as password resets, etc)
Storing password hashes with salt it correct. However, it's easy to get even that much wrong. Sure, right now SHA256 will keep the baddies at bay, but give it a few years. Suddenly, SHA256 might not seem so secure anymore. You need to use BCrypt, a future-proof hashing algorithm.
Problem with doing just one pass of SHA256 is it is too fast and one with great hardware can generate rainbow tables for lots of salts easily...to get around this you need to perform key stretching....kI'm not going to give you a lesson on key stretching but the bcrypt implementation that people talk about performs key stretching. If you want a more modern alternative to bcrypt which uses HMACSHA256 or 512 in .NET, I recomend this API:
https://sourceforge.net/projects/pwdtknet/

Latest stream cipher considered reasonably secure & easy to implement?

(A)RC4 used to fit the bill, since it was so simple to write. But it's also less-than-secure these days.
I'm wondering if there's a successor that's:
Code is small enough to write & debug within an hour or so, using pseudo code as a template.
Still considered secure, as of 2010.
Optimized for software.
Not encumbered by licensing issues.
I can't use crypto libraries, otherwise all of this would be moot. Also, I'll consider block algorithms though I think most are pretty hefty.
Thanks.
Honestly your best bet is to go use a crypto library. Its an already tested platform and when even the crypto libraries can/do have trouble with implementing the algorithms... Its better to use the pre-existing crypto libraries, its already tough enough to do encryption/decryption correctly using the API as it is as in this post on Coding Horror: Why Isn't My Encryption.. Encrypting?
Now I've gone to the Wikipedia article on Stream ciphers it might be worth going through the list of ciphers on the article, there has been several ciphers developed since RC4 in 1987, and to my very limited cryptography knowledge some of them seems like they might be more secure than RC4. You may also want to consider checking out the Wikipedia article on eSTREAM. There are several ciphers which are in the portfolio: HC-128, Rabbit, Salsa20/12, SOSEMANUK.
No cipher is easy to implement, especially symmetric ciphers and they never will be. There is a lot that can go wrong, and most programmers don't realize this. You need to do a lot more reading into this topic.
With block ciphers you must be concerned with the mode you use, and different modes fill different needs(But ECB is always the wrong choice). You must also be very careful about maintaining a unique IV for each message. If you are using a "password" as your key then you have to use a string2key function.
Stream ciphers don't have IV's or modes, and this actually makes things more difficult. A stream cipher function accepts only a key and the output is a "PRNG stream" that is infinity large. This stream of random data is then XOR'ed with your message. So if you use the same key, you will get the same PRNG stream. If an attacker knows the plain text of 1 message (or a part of a message) then he can XOR out the PRNG from the cipher text and then decrypt all other messages using that key in constant time O(1). For a stream cipher to be practically secure you can never reuse the same key.
I highly recommend that you pick up a copy of Practical Cryptography, which has a few chapters dedicated to Symmetric Cipher attacks. This book is straight to the point and doesn't require a lot of math. If don't really care about implementing your own then you can use a proven cipher implementation such as Jasypt which "just works" in a very secure way.

Resources