# Which method to generate one time password?

I'm looking for a concrete algorithm to generate one time passwords. The situation is as follows:

Alice and Bob exchanged a passphrase over a secure channel in the beginning. They want to symetrically encrypt data in the future, and every consecutive enryption/decryption process should use a one-time password.

For every single data exchange process it is considered that they remember the initial passphrase, but nothing else. It is possible to exchange additional metadata in cleartext alongside with the payload.

I looked at hash chains, but the problem with that is that they need to ensure that never use the same number of iterations twice and decrease it everytime. As I said above, they can't remember anything but the initial passphrase.

Second thought was to use a key derivation function, for example PBKDF2. The number of iterations could be statically (high enough), and the salt could be exchanged with the payload. But as a cryptography novice, I'm not sure if this is secury enough, because it wasn't made for that purpose, as far as I understand this. Or was it?

Are there alternatives? Or would it be sufficient to use a KDF in my case?

Yes, your best choice is indeed to use a key derivation function.
However you should consider using the TLS-PSK set of cipher suites for your needs. If you use the variant with DHE / ECDHE key exchange (recommended) included you don't have to rely on your passphrase being strong for security, both the password and the discrete logarithm have to be disclosed in order to recover the message.
In both cases (with and without additional key exchange) the TLS nonces will be used to aid master secret derivation, meaning you get unique master secrets even if re-use the static passphrase without additional key-exchange.

As for the cipher suites something like TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 seems like the best choice at the moment or TLS_PSK_WITH_AES_128_GCM_SHA256 if you want to solely rely on your passphrase. As for what to input as PSK, either a hash of the passphrase directly (high entropy case) or a master secret like constructed in the next paragraph(s) is fine (in the low entropy case).

If you're only relying on your passphrase for confidentiality and your passphrase may have low entropy, you should use a password-based key derivation function (PBKDF), for which you can negotiate a key as follows:

$$A\rightarrow B: R_A$$ $$A\leftarrow B: R_B,C_B$$ $$A\rightarrow B: C_A$$

with $$R_A,R_B$$ being random 128 bit strings and $$C_A,C_B$$ being key-confirmation values. The 128/256-bit master secret $$MS$$ is calculated via $$MS=PBKDF(PW,R_A||R_B)$$ with the second input being the salt. From this you can derive as many keys as you want via HKDF-Expand and you can calculate the $$C_A=HMAC_{MS}(R_A||R_B),C_B=HMAC_{MS}(R_B||R_A)$$, note that the order matters or replay attacks apply.

As for the algorithmic choices for this and the following approach you should use SHA-256 or SHA-3-256 as your hash functions and Argon2 as your PBKDF.

If you're only relying on your passphrase for confidentiality and your passphrase has high entropy, you should use a key-based key derivation function (KBKDF). More concretely you want to use HKDF with a salt that you exchanged just-in-time via the above protocol with HKDF-Extract replacing the PBKDF.

TL;DR: Use TLS-PSK with strong cipher suites and / or apply a strong PBKDF (like Argon2) using a negotiated salt for key derivation.

I suppose you could use the initial passphrase as the key of a block cipher to encrypt a session dependent non-secret data, e.g. date and message serial number etc., and use that for your purpose.

Nowadays, One time password are generally used for two-factor authentication. For example, in Banking System, before making an transaction, an OTP is sent to user in order to verify his/her authenticity. There are many schemes developed by researchers. Just have a look at https://www.cs.umd.edu/~jkatz/papers/password.pdf. It performs authentication even with weak password.

It's better if you do more clear your objective of generating passwords. What cryptosystem do you wish to use? Are you looking for efficient scheme? A simple technique can be found at http://spacebug.com/tableless_secure_one_time_password.