Encryption based solely on XORing with concatenated hash values I have recently read a bit about Lamport signatures (especially the approach using hash ladders to save disk space) and I found it very interesting that it entirely depends on a hash function.

So I asked myself the following question:

When you have a plaintext $p$ and hash it and concatenate it with its hash again and so on: plain -> $H(p) + H(H(p)) + H(H(H(p))) + ...$ ($n$-times) 


is this a good source for randomness? Why not?
Does the attacker having a look at this output have any advantages in guessing the plaintext for large $n$?


You have some file you want to encrypt. Hash the file with a good hash function (e.g. Keccak). Then concatenate this hash with a password you choose.
From this you derive a hash concatenation like above until it is as long as the file you want to encrypt; lets call it "hashchain". Then XOR your file with the hashchain and when you are finished you write the hash of the original file to the beginning of your encrypted file. Destroy original file and hashchain.

When you want to decrypt, take your password and the hash of the original file (which we have written to the beginning of the encrypted file), concatenate and hash this until you have a file which has the size of the original file. XOR both again and you get back your file from the beginning.

Note: Using password and hash of the original file as the beginning for the hash chain makes us able to use the same password for encryption of different files.


Is there a reason why this is not secure?




I have no only superficial knowledge about cryptography, please keep this in mind when answering.
1) is this a good source for randomness? Why not?


It is certainly not a cryptographically secure PRNG. In order to be a cryptographically secure PRNG, it must not be possible to predict the next output based on the current output. With your algorithm, the next output is predictable, since it's just H(previous_output) and, according to Kerckhoff's principle, you should assume the attacker knows the hashing algorithm. 


  2) Does the attacker having a look at this output have any advantages in guessing the plaintext for large n?


The attacker only has to guess or know the first block of plaintext. Once the attacker knows this, decrypting the rest of the plaintext is easy: for the first block, the ciphertext C is H(password) ^ M, so H(password) = C ^ M. So once the first block of plaintext is known, the attacker knows H(password), and can calculate H(H(password)), H(H(H(password))) etc.


  3) Why is the following encryption a bad idea? You have some file you want to enrcrypt. Hash the file with a good hash function (e.g. Keccak). Then concatenate this hash with a password you choose. From this you derive a hashconcatenation like above until it is as long as the file you want to encrypt lets call it (hashchain). Then XOR your file with the hashchain and when you are finished you write the hash of the original file to the beginning of your encrypted file. Destroy original file and hashchain.


Password have the habit of having low entropy, which makes them excellent targets to brute-force. If the first block of the file's plaintext reveals any information about whether the file is successfully decrypted, the attacker only has to calculate H(plaintext_hash || password) and xor the first block to see if the attack is successful. Most hash functions are fast, and attackers can easily try millions of passwords per second. 

Even if the first block does not reveal any information, if you reuse the same password, an encryption oracle attack with a chosen plaintext can choose an all-zero plaintext. Then the first block simply becomes C = H(plaintext_hash || password) ^ 0 = H(plaintext_hash || password). Since the attacker knows the plaintext hash, the password can still be brute-forced in the same way.

Given my experience with cryptography, that's probably just the tip of the iceberg.