I have next to no experience or knowledge of encryption, so I am asking this out of pure ignorance. Let's say that I got bit by ransomware (thank God I have not!). On my desktop is one solitary file that I downloaded off the internet. That file gets encrypted. I know where to get the exact copy of that file and re-download it. Wouldn't it be possible to compare the original and encrypted versions and work out the necessary key?
Suppose we use a very simply encryption algorithm, like the rotation cipher. A => B, B=>C, C=>D, etc. This would be a rotation of 1 to the right. The algorithm would be "Letter+1". Very easy to decrypt, right? Let's make it slightly more complicated by letting the number of letters we displace be a random value between 0-26. We get this random integer value by using
int offset = rand() % 26;
char ROT = (Letter + (char)offset) % 26; //let Z + offset loop around
Note that every time you run the rand() function, you're generating a sequence of random numbers. Because the rand() method is a pseudo-random number generator, the sequence of random numbers will always be the same, every time you run the application. Here's an example:
Random output sequence the first time the app is run: {23,14,21,7,16,3,21...}
Random output sequence the second time the app is run: {23,14,21,7,16,3,21...}
However, if you seed the random number generator, you're going to generate a different sequence of random numbers. But, every time you use the same seed, you'll generate the same sequence of random numbers. So, if we treat the key as the generator of the seed for random numbers, can we derive the key from a sequence of random numbers?
Even if I give you the code which generates the random numbers, the plain text which was encrypted, and the resulting cipher text, is it possible to derive the key from a simple ROT cipher without using brute force?
//from rand.cpp in the stdlib
// Seeds the random number generator with the provided integer.
extern "C" void __cdecl srand(unsigned int const seed)
{
__acrt_getptd()->_rand_state = seed;
}
// Returns a pseudorandom number in the range [0,32767].
extern "C" int __cdecl rand()
{
__acrt_ptd* const ptd = __acrt_getptd();
ptd->_rand_state = ptd->_rand_state * 214013 + 2531011;
return (ptd->_rand_state >> 16) & RAND_MAX;
}
I'm not a crypto-analyst, so I can't say with any authority, but I imagine it would be difficult?
If I was going to try to attack this encryption method, I'd brute force it and use a large bank of computers and have them start creating sequences of random numbers to try to match the known sequence of random numbers. We'd just create a loop which iterates through every possible random number seed until we find a perfectly matching sequence of random numbers. But hey, that's brute forcing and if we can force a brute force attack to be the best chance, then the encryption system wins. All we'd have to do is exponentially increase the time it takes for the brute force to be effective. 100,000 years on one computer, maybe 1 year with 100,000 computers?