I am just wondering if you are supposed to write a sort of really secure application with data being transmitted over insecure networks, what kind of encryption algorithm will you use it in order to make it safe ? I know several c++ libraries for encryption providing nice functions with different algorithms, but i'm not quite sure which cipher to use - AES, DES, RSA, Blowfish or maybe something more different ?
Please provide your ideas and suggestions.
While some encryption algorithms are easier to break then others, the weak spot is more about key generation. If your key generation algorithm is predictable, it will be easier to figure out your key and decrypt the packet.
So, I wouldn't sweat which encryption algorithm (AES is fine). But make sure you have a good source of real randomness to generate your keys.
If you are on any of the common POSIX OS, look into using /dev/random to generate your key.
use AES for data encryption and use RSA to exchange AES key between parties
You have listed too few requirements for your encryption needs. It depends on circumstances.
For example, if both end-points of the communication link are trusted, you could just worry about encryption and have both of them produce public-keys for the other end to encrypt information with. In this case, RSA would be my personal choice.
However, if you do not trust the other end-point, and am using the encryption to determine whether it "has the key", then you would be counting on preset keys, rather than private/public encryption. In this case, Triple DES (DES is considered a little weak these days) may be a good choice.
Hope this helps!
Any of the well know ciphers have well understood levels of security so that part is easy. I'd be more concerned about the quality and trust level of the library you use and bugs in your use of it. Have you considered using external programs like ssh to do the key gen and handle the connection, and drive that with an API library?
Crypto++, perhaps the best known, largest, and best crypto library for C++, contains several algorithms you can use. It can also give you a good cryptographically secure random library for use with these algorithms.
According to their FAQ, that depends quite a bit on what you want to do. From their recommended list of algorithms:
block cipher: DES-EDE3, AES, Serpent (Serpent is slower than AES but has a larger security margin and is not vulnerable to timing attacks.)
stream cipher: any of the above block ciphers in CTR mode
fast stream cipher: Salsa20, Panama, Sosemanuk (available in version 5.5)
hash function: SHA-256, SHA-512, Whirlpool
message authentication code: HMAC/SHA1 or HMAC with one of the above hash functions
public key encryption: RSA/OAEP/SHA1, ECIES
signature: RSA/PSS/H, ECDSA/H, which H one of the above hash functions
key agreement: DH, ECDH
random number generator: RandomPool, AutoSeededRandomPool
We can't give an exact answer because there isn't one without knowing more about what you're trying to accomplish.
First of all you have to split up symmetric block ciphers with public key ciphers:
they have really different performances
their implementation is really different
their strenghts/weaknesses are based upon different factors
By the way:
DES is not considered secure anymore, you should always avoid using it
AES is still considered safe (you could use 256 bits keys)
RSA's (and other public key algorithms like ElGamal, Ellipctic Curve) security is based on the hardness of the mathematical problems on which these algorithms are based. For example: number factorization. If the number of bits you use to store the keys are big enough you can consider them enough safe.
However things can change according to the power of CPUs in few years so you shouldn't consider them safe forever..
One thing to consider is that public key ciphers are usually slower than block ciphers, that's why commong protocols usually use the first ones to exchange a simmetric key that then is used with an algorithm like AES.
The answer is: don't. If it has to be secure and you ask this question it means that you need to find a security expert to do it. You are not going to design a secure protocol by asking for help on SO. You can [maybe] use an existing protocol such as ssh or TLS, but if you roll your own you will fail.
If you want to transmit data over an insecure network, you need more than a cipher, you need a secure protocol, potentially including key distribution and authentication.
If you're really serious about crypto implementation, not just doing it to understand the basic mathematics of cryptography, then you need to do more than implement the number-crunching correctly. You also need to worry about side-channel attacks. For example, if your implementation takes a different amount of time depending on the key, as is common, then an attacker can deduce information about the key from your various response times. And that's just the basic algorithm, never mind putting it all together.
This is in general an unsolved problem and an area of ongoing research. Most or all implementations are flawed, although for the latest versions of well-used libraries probably not in a way that anyone has publicly announced they can exploit. Timing-based attacks on OpenSSL have been demonstrated in the past, albeit only on a highly predictable local network AFAIK. You can basically spend as long as you like on it, up to and including your entire career.
In practice, just use SSL, in whatever implementation comes with your platform.
Actually, we may not need to know all the details. But, IMHO, cascade these algorithms with Chain Of Responsibility Pattern, or Composite + Strategy.
Related
I'm looking to encrypt license keys on an audio software plugin. The biggest risk to the integrity of the license keys is small-time crackers decompiling the code and looking for the encryption key. My solution is to store an arbitrary number in the code and feed it to an algorithm that will obfuscate the encryption key while still allowing me to differ the key between projects (I'm a freelancer).
My question is - will seeding the C++ random number generator create the same psuedo-random encryption key every time, or will it differ between runs, libraries, etcetera. It's fine if it differs between operating systems, I just need it to not differ between SDKs and hosting softwares on the same computer.
srand and rand will produce the same sequence of numbers when you use the same implementation. Change compilers, even to a newer version of the same compiler, and there are no guarantees,
But the new random number generators, introduced in C++11 and defined in <random>, are requires to generate the same sequence of numbers on all implementations.
I'm trying to re-implement the RSA key generation in C++ (as a hobby/learning playground) and by far my biggest problem seems to be generating a random number in range x,y which is also cryptographically secure (the primes p and q, for example).
I suppose using mt19937 or std::rand with a secure random seed (e.g. /dev/urandom or OpenSSL RAND_bytes etc) would not be considered 'cryptographically secure' in this case (RSA)?
ISAAC looked promising but I have zero clue on how to use it since I wasn't able to find any documentation at all.
Notably, this is also my first C++ project (I've done some C, Rust etc before... So C++ at least feels somewhat familiar and I'm not a complete newbie, mind you).
I suppose using mt19937 or std::rand with a secure random seed (e.g. /dev/urandom or OpenSSL RAND_bytes etc) would not be considered 'cryptographically secure' in this case (RSA)?
No, those are not cryptographically secure for basically any purpose.
ISAAC looked promising but I have zero clue on how to use it since I wasn't able to find any documentation at all.
Well, it stood the time I suppose. But I'd simply use a C++ library such as Crypto++ or Botan or something similar and then just implement the RSA key pair generation bit, borrowing one of their secure random generators. With a bit of luck they also have a bignum library so that you don't have to implement that either.
Say, if I have a byte array of a various length and a pass-phrase, what is the quickest way to encrypt it in a platform-independent way?
PS. I can make a SHA1 digest on the pass-phrase but how do I apply it to the byte array -- doing a simple repeated XOR makes it too obvious.
PS2. Sorry, crypto guys, if I"m asking too obvious stuff...
A Hash (like sha1) create a one-way result, you cannot decrypt a hash. XORing the data is not secure by any means, don't do that.
If you need to be able to decrypt the data, then I suggest using something like Twofish which uses a symmetric key block cipher and is not restricted by licensing or patents (thus you can find platform independent reference code).
Hello all
I need to encrypt text what is the best encryption to use programmatically ?
In general I have input file with string that I need to encrypt then read the file in the application
Decrypt it for the application flow .
with c++
The strongest encryption is to use a one-time pad (with XOR for example). The one time pad algorithm (unlike most other commonly used algorithms) is provably secure when used correctly.
One serious problem with this algorithm is that the distribution of the one-time pad must be done securely and this is often impractical. If it were possible to transmit the one time pad securely then it would typically also be possible to send the message securely using the same channel.
In situations where it is not possible to send information securely via another channel, public key cryptography is used. Generally the strength of these algorithms increases as the key length increases, unless some critical weakness is found in the algorithm. RSA is a commonly used public key algorithm.
To get strong encryption with public key cryptography the keys tend to be large (thousands of bits is not uncommon) and the algorithms are slow to compute. An alternative is to use a symmetric key algorithm instead. These can often get the same strength encryption with shorter keys and can be faster to encrypt and decrypt. Like one-time-pads this also has the problem of key distribution, but this time the key is very short so it is more feasible to be able to transfer it securely. An example of a commonly used symmetric key algorithm is AES.
One time pad is the strongest, but probably you are looking sth that you can use easily in your application. Check this page to learn about strength of algorithms - http://security.resist.ca/crypt.shtml and here you have a C++ library: crypto++ (the link points to a benchmark that compare performance of different algorithms) http://www.cryptopp.com/benchmarks.html.
The answer depends on what you mean by "strong encryption".
When cryptographers talk about strong encryption modes, they usually expect that it has at least two properties:
confidentiality: I.e. it is not possible to find any information about the plaintext given the ciphertext (with the possible exception of the plaintext length).
integrity: It must not be possible for an adversary to modify the ciphertext, without the receiver of the message noticing the modification.
When cryptographers call a cryptosystem "provably secure under some assumption" then they typically mean that the cryptosystem is secure against chosen ciphertext attacks unless the assumptions (e.g. there is no efficient algorithm for some well known problem) are not satisfied.
In particular, some of the other answers claim that the one-time pad is the most secure algorithm. However, the one-time pad alone does not provide any integrity. Without any modifiction it is easy to modify a ciphertext, without that the receiver notices the modification. That means that the one-time pad only satisfies a rather weak security notion called "perfect secrecy". I.e. nowadays it is quite misleading to call the one-time pad "provably secure", without mentioning that this only holds under a security model that does not include message integrity.
To select a strong encryption mode an might also look at practical aspect. E.g., how much cryptanalysis has gone into an encryption mode, or how well has the cryptographic library that implements the algorithm been analyzed. With that in mind, selecting a well-known cryptographic library, properly encrypting with AES, authenticating with HMAC is going to be close to optimal.
My application needs to use a couple of hard-coded symmetric cryptographic keys (while I know that storing a public key would be the only perfect solution, this is non-negotiable). We want the keys to be stored obfuscated, so that they won't be recognizable by analyzing the executable, and be "live" in memory for as little time as possible - as to increase the difficulty of a memory dump retrieving them in clear-text. I'm interested in using C++ features (using some sort of scoped_key comes to mind). The solution must be portable - Windows, Linux, MacOS -, so it cannot take advantage of the operating system crypto API.
How would you go about designing such a system? Thanks a lot.
All you're going for here is security through obscurity. If you have one of us come up with an idea, you won't even have that.
John Skeet has a good article on this too.
Do something random is all I can say.
your scoped_key can be simply a KeyHolder object on the stack. Its constructor takes the obfuscated buffer and makes a real key out of it and its destructor zeros out the memory and deallocates the memory.
As for how to actually obfuscate the key in the binary, One silly choice you might try is put inside a much larger random binary block and remember its offset and size and probably XOR it with some short random sequence.
If you do the XORing thing you can actually avoid ever having the real key in memory. simply modify the decryption to read a byte from the key and before using it, to XOR it with the appropriate value.
*Add here disclaimer on how foolish security through obscurity is*
Have you considered if this is actually the weak point in your program? Let's assume for the sake of argument that you're doing a license check - though other checks apply equally well. No matter how well hidden your key, and how well obfuscated your algorithm, at some point you have to do something like this:
if(!passesCheck()) {
exit(1);
}
Your potential adversary doesn't have to find the key, decrypt it, figure out the algorithm, or anything else. All they have to do is find the location in the code where you determine if the check succeeded, and replace the 'jnz' instruction with a 'jmp' to make the test pass unconditionally.
You should look into Tamper Resistance software, such as Cloakware and Arxan.
TR is NOT cheap :)
If you do not take advantage of whatever platform you will run on, you cannot guarantee that you can effectively hide a symmetric cryptographic key in your program. You can assume that an attacker will have a debugger and will eventually figure out how to set a breakpoint in the function that has to use the key to decrypt. Then it's game over.
Why not look at steganography, as you can hide the key in an image. It is possible to find the key, but if the image doesn't follow an obvious pattern (such as an image of space would) then it may be harder. This can be cross-platform.