An answer to your question will depend on what exactly you're using the counter value for.
There are various OTP schemes. One, HOTP, is using a counter, so maybe you're talking about an HOTP implementation. However, your question could also imply that you have a list of valid passwords lying around and you need to remember which one is the next valid one. This would strike me as a bad idea altogether and you can easily improve on it and solve your counter problem at the same time. So if you aren't talking about an HOTP counter or a similar solution, here's a suggestion:
Destroy used-up passwords
There is no need to keep around passwords which are already "used up". I can't immediately see why keeping old passwords around might be a problem, since they're no longer used, but if there is no need to keep them, I would make sure to destroy them. Depending on what you're using these passwords for, you might compromise forward security by keeping them around, for example.
If you throw away old passwords, you also fix the counter issue - you don't need to keep a counter at all because the next valid password is just the next one in your list. You might also get a bit of extra security by choosing one of the remaining passwords randomly instead of always taking the next one.
Other approaches
But if you don't need the random password selection, there are simpler solutions is an easier solution doesn't require you to store a list of passwords, for example
HOTP is basically building a hmac given a secret and a counter and using
the result as a password. TOTP uses the time instead, so it can't be used
with paper lists of passwords, but has the advantage of making it possible to expire OTPs.
Securing HOTP server-side
Edit: Added this section to better answer the updated/edited question
I think what you need to worry about when using HOTP is not whether to keep the counter secure, but how to keep the secret secure that you're using. If an attacker gains access to the secret key, he/she can generate all past and future passwords. With this knowledge, he might guess a range of counter values to try. Knowledge of the counter value itself is less dangerous, since without the secret, you can't produce a valid password.
So it seems to me that since you already need a solution to store the secret key securely, you could just err on the side of caution and store the counter value in the same way. If you don't want that, I'd simply add an additional column to my user table in the database and store the counter value there.
You could encrypt this counter value beforehand using another password (and random iv, so identical counter values don't produce identical ciphertexts!), but frankly I don't see much gain for the following reasons:
- The counter value itself isn't helpful to an attacker unless he
already has the user's password list or your secret key, and in
both cases, you're pretty much screwed anyway. (One exception: With knowledge of the counter, an attacker might social-engineer the coresponding password from a user, using his knowledge of which password came next to convince the user that he was legit)
- Encrypting will only protect the counter when someone manages to
steal your database, but can't steal the encryption key or run the
decryption code on his behalf. I think that's an unlikely scenario.
Securing sensitive server state by not storing anything sensitive
Lamport OTP is a simple, beautiful solution to OTPs which doesn't need a shared secret and which you might also consider.
Basically, the idea is to hash a hash of a hash of a hash.... For a simple
idea on how it works, consider the following OTP solution: Take a secure password hash function H(x), and hash an initial random seed secret S which only you know. To generate the list of passwords for the user, take the result and hash it again, and again, and again, as many times as is necessary to yield the required number of passwords. So basically you're building a list of OTPS:
[ H(S), H(H(S)), H(H(H(S))), ...]
Now one problem you have is that if you use the hashes directly as passwords, if an attacker learns just one of them, he can calculate all the future ones, too.
You can fix this in a variety of ways. For example, you could take the resulting hash and use it as a password to encrypt another secret string, and then use the encrypted string as the password to put on the list and verify against. (I just made that up - don't use this without carefully thinking about whether this is secure, as it probably isn't).
Lamport OTP does it way more clever. It's basically sending the hashes backwards; e.g. you calculate the first 100 hashes based on a seed and give the user a list of them in reverse order. So the first one he sends is number 100.
The next one he sends is number 99. The server can now check if H(OTP99) = OTP100. Because Hash functions are one-way, knowing OTP 100 doesn't help an attacker to get at OTP99.
The nice thing here is that the server doesn't need to store anything that can be compromised. It must keep the last sent password (e.g. hash) stored somewhere, so in the beginning it must have the value for OTP101, and when the user successfully logs in with OTP100, it must then replace OTP101 by OTP100, but even if an attacker gets to know the currently stored value at the server side, it won't help him, since what he actually needs to know is S (or any of the derived hashes), and they're hopefully secure at the client. The server never needs to store S at all, meaning that after you generate the list of passwords and OTP101 to store at the server, you no longer need to know S or any of OTPs 1-100. This strikes me as a very beautiful solution which completely sidesteps your question of whether you need to keep the counter value secure - with Lamport, there isn't anything to keep secure at the server side.
I've simplified a bit, read up on the algorithm/protocol to see how to implement this in detail.