|
The problem is that, if you do this, you're not using a one time pad anymore. You're using a stream cipher. The difference is in the nature of the security guarantees. Almost every cryptographic primitive is "computationally secure", which means the best-known attack is to try every key, and that would take beyond the heat death of the universe. One-time pads have "information-theoretical security", which is that even if you try every possible key, you don't learn the contents of the message, because every possible message has a corresponding decryption key that will produce it from the ciphertext you are trying to break. The reason why this is the case is because the size of the message space is equal to the size of the key space. In every other cryptosystem, you have a key space that is much smaller than the message space - say, 256 bit AES keys, or 512 bit SHA-2 hashes, for messages that can have many billions of bits in them. It's unlikely for something that wasn't the key to happen to decrypt to a valid-looking message under this scenario. But with a one-time pad, you are actually brute-forcing the message space by brute-forcing the key space. Even if you knew the hash of the plaintext, it wouldn't help. You'd just be brute-forcing whatever hash you used to find collisions. This property goes away if you start repeating key stream bits by any deterministic process. Hence why just sending a PRNG seed is a bad one-time pad. This is also the difference between /dev/random and /dev/urandom. Linux generates randomness from a PRNG, but it's seeded by unpredictable hardware events and other sources of entropy, and there's a bunch of logic to estimate how much entropy is available. /dev/random specifically blocks until that estimate is positive, so that one-time pads and the like don't repeat bits. (In fact, this is basically the only time you should be using /dev/random! /dev/urandom is perfectly acceptable for all other cryptographic use cases!) |