4
$\begingroup$

I'm doing some exercises. Of course, I have read about the weaknesses of the Vigenère cipher because it repeats the key. But what if I use a different hash every time? The hash of the "key + an increasing number". In this example, I encode a plaintext just with a sum of every single char (text[0] + pswhash[0], and so on). Blocksize is 128 because I use SHA-512.

    f = open(filename)
    f2 = open(filename+'.encoded','w')
    x = 0
    while True:
        string = f.read(blocksize)
        if not string:
            break
        pswhash = sha512((psw+str(x)).encode('utf-8')).hexdigest()
        f2.write(encode(string, pswhash))
        x+=1
    f.close
    f2.close
    print("File encoded.")

How safe could this be? Is this a real one-time pad?

$\endgroup$
1
  • 2
    $\begingroup$ SHA512 produces a 64-octet result; use that (and that length) not the hex form which is hugely redundant/correlated. $\endgroup$ Oct 7 '16 at 3:16
6
$\begingroup$

Is this a real one-time pad?

No, it's not a one time pad; as the keystream is not generated from a truly random process, hence you don't get the informational security guarrantees that you'd get from a true OTP.

Instead, it's a stream cipher; in particular, counter mode (with SHA512 is the "block cipher"; in counter mode, the block cipher needn't be invertable).

It's actually decent at providing privacy (albeit not very fast at it); however, it still would need some integrity protection (unless you're absolutely positive that an attacker cannot alter the ciphertext)

$\endgroup$
1
  • 5
    $\begingroup$ 'decent' if you use actual SHA512 (or other good hash) output, but not if you effectively use 4 bits of keystream per octet of plaintext :-{ $\endgroup$ Oct 7 '16 at 3:14
3
$\begingroup$

No, that’s not a “real one-time pad”.

As I explained in another answer of mine…

Per definition, OTP requires the “key“ to be…

  1. a truly random one-time pad value,
  2. generated and exchanged in a secure way.
  3. at least as long as the message, and
  4. only to be used once.

At the very least, your idea fails the definition in points 1 (calculated checksum != truly random) and 3 (SHA512 has a fixed length, which is bound to differ from the plaintext message length).


Besides that, I hate to disappoint you – but the idea isn’t very new either. Cryptographically secure hashes represent nice cryptographic primitives which are inviting to build upon. Yet, such hashes are also build to be rather “slow”, which raises the question why one would decide to risk security pitfalls and accept slower performance when faster, well-vetted stream and block ciphers are available (most prominent example: AES).

Nevertheless, you might be interested to check up on some related Q&As as the answers to each of these questions hold information which might help you understand things a bit better:


Last but not least, to answer your “how safe this could be?” – it could be much more secure than what you’re doing right now. Looking at your code it’s obvious you simply hash $k|m$.

pswhash = sha512((psw+str(x)).encode('utf-8')).hexdigest()

Bluntly combining and hashing both key and message is about as bad as it sounds: don’t do it! There are several issues with that approach which might not seem obvious at first sight, but those issues can and will break your neck if you let them. Instead of writing a multi-page essay about that, I’ld rather like to advise you to use a HMAC based on SHA512 (at the very least) since HMACs are made to hash things using a password. You can use HMAC to create a KDF out of SHA512 quick and easy.

Even better would be using a dedicated Key Derivation Function. Or course, a HMAC-based Extract-and-Expand Key Derivation Function (HKDF) is simple and easy to implement… but honestly – from a security point of view – I would recommend using something more dedicated like PBKDF2 (Password-Based Key Derivation Function 2). Combine that with one of the faster, well-vetted ciphers like AES and the information you plan to encrypt has a good chance to be more secure than you could wish for.

$\endgroup$
0
$\begingroup$

There's nothing I can add to the other answers. But, I can reiterate the fact that a one time pad requires the key material to be generated through physical processes (i.e. dice or diodes etc.) Use a laser, use a typewriter or an ionisation smoke detector. Use bananas or cameras. Do not use program code.

Still, this leads us to a deeper question. Who is teaching the young players that a one time pad can be algorithmically generated? Over and over we see questions modifying, improving and extending the one time pad definition. 359 OTP tagged questions as of this post. Who is spreading this nonsense? That's the true question.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.