# Using a SHA512 hash to encrypt data

How can I judge the level of security with the following algorithm:

I create a 64 byte hash using SHA512 via some input. I use this hash to iterate over the plaintext, byte by byte, and similarly iterate over the hash byte by byte XORing each byte of the plaintext with a respective byte from the hash like this (in C#):

for (int i = 0; i < data.Length; i++)
{
if (j == key.Length) j = 0;
data[i] = (byte)(data[i] ^ key[j++]);

}


where key is a byte array containing the hash. Issues of how the code acquires the key aside, is this secure? (Apologies if I am not framing this with the proper terminology). I am not using a salt. The input which is used to create the hash can be of any length (up to being reasonable; i.e., not a huge block of text).

• If the message is longer than 64 bytes, this turns into a variant of the vigenere cipher, with its known weakenesses. If you use the key more than once, it turns into a many-time-pad, which is also very weak. – CodesInChaos Nov 18 '15 at 16:26
• Vigenere would imply that the keylength is unknown, which was for a long time the main problem, when frequency analysis could already be used to break Caesar. – tylo Nov 18 '15 at 16:36
• Related questions: [key-reuse] [one-time-pad] – CodesInChaos Nov 18 '15 at 16:52
• @tylo It turned out there is a fairly simple statistical method to identify the key length used in a Vigenere cipher. So there is no practical difference between a Vigenere cipher with a known and an unknown key length. – kasperd Nov 18 '15 at 21:41
• There is evidence for frequency analysis in the 9th century by Al-kindi. Vigenere was broken in 1863. And that breakthrough was how to find out the key length. The rest was just using techniques, which were a millenium old already. That was the problem, even if it isn't any more today with our current knowledge. – tylo Nov 30 '15 at 13:41

No it's not. It is really bad.

Basically, this is a stream cipher, where your keystream is $key | key| key|key....$. This is really bad, similar to the level of "using OTP twice". As If you take a block of size keylength, and XOR two such blocks, then you get the XOR of the plaintexts. Depending on the nature of the plaintext, this can be really easy to guess.

If you want an easy encryption scheme, like XOR the plaintext with a keystream, use a stream cipher or a block cipher in OFB mode of operation. If you want a construction with SHA512, that is also possible, see e.g.

However, since hash functions have different security properties than stream ciphers, it might be better to use a construction which is actually intended to be used this way. In a similar context, Bruce Schneier wrote (about ciphers based on hash functions):

While these constructions can be secure, they depend on the choice of the underlying one-way hash function. A good one-way hash function does not necessarily make a secure encryption algorithm. Cryptographic requirements are different. For example, linear cryptanalysis is not a viable attack against one-way hash functions, but works against encryption algorithms. A one-way hash function such as SHA could have linear characteristics which, while not affecting its security as a one-way hash function, could make it insecure in an encryption algorithm such as MDC. I know of no cryptanalytic analysis of particular one-way hash functions as block ciphers; wait for such analysis before you trust any of them.

• I read the link "is it feasible..." and note this: If the attacker can guess some plaintext_n, he can derive pad_n from ciphertext_n and from this all the following pad_i - which means that he can read the rest of the message. BUT I don't understand in the sense that 1) how would an attacker guess some plaintext_n? And even if he could guess plaintext_n (but also: How would he know he's right?) and could therefore derive key_n, how could knowing key_n help in figuring out any other key(n)? Apologies if I'm not making sense. – Ron Nov 18 '15 at 16:38
• @Ron Natural language has enough redundancy that you get partial plaintext recovery if you use the same pad twice and nearly perfect recovery if you use it three times. – CodesInChaos Nov 18 '15 at 16:50
• @Ron: imagine you encipher a file known to contain many long sequences of 00 bytes (as many files found in practice do). These long sequences of 00 bytes in the plaintext will degenerate into blocks of size key.Length that are identical in the ciphertext. These blocks of ciphertext have, precisely, the value of key[]. – fgrieu Nov 18 '15 at 16:55
• @Ron Vulnerable against known plaintext. Stop now and use a stream cipher. Your code can be broken by anybody that has followed an intro course into crypto (e.g. the one by Dan Boneh). This comment may contain product placement. – Maarten Bodewes Nov 18 '15 at 18:13
• @Ron If you want to use SHA512 as stream cipher, use it an an existing mode, like CTR. CFB and OFB work as well, as long as you pass in the key on each iteration and not just in the beginning. But I'd rather use a dedicated stream cipher like Salsa20. – CodesInChaos Nov 18 '15 at 20:17