I'm currently thinking about a web-app that can go offline (after being online) and still be able to provide authentication to the user securely.
(For example, in a multiuser environment, it's quite essential to prevent other users' access.)

Right now, I was considering a password-hash authentication with some salt, and just saw this SO question: 
https://stackoverflow.com/questions/7879641/user-authentication-in-offline-web-apps

But since this is a web environment, I have to assume that others have access to the source code of the app, and thus the salt itself is leaked.
(Also, the attacker might use the hash itself to bruteforce the password itself.)

So...to summarize, my 2 questions are:


Is salting effective even when it's leaked?
I'm guessing no to the question, since it takes O(X^(m+n)) to bruteforce the unknown...
 and it gets worse when the attacker uses the password hash to bruteforce the passwwd..
Are there any effective (secure) ways to authenticate the user?
Any good way to generate a DES key for encrypting the user's data
 (and provide a way for the server to distinguish between tampered data and real one?)


Yes, bcrypt has a maximum password length. The original article contains this:


  the key argument is a secret encryption key, which can be a user-chosen password of up to 56 bytes (including a terminating zero byte when the key is an ASCII string).


So one could infer a maximum input password length of 55 characters (not counting the terminating zero). ASCII characters, mind you: a generic Unicode character, when encoded in UTF-8, can use up to four bytes; and the visual concept of a glyph may consist of an unbounded number of Unicode characters. You will save a lot of worries if you restrict your passwords to plain ASCII.

However, there is a considerable amount of confusion on the actual limit. Some people believe that the "56 bytes" limit includes a 4-byte salt, leading to a lower limit of 51 characters. Other people point out that the algorithm, internally, manages things as 18 32-bit words, for a total of 72 bytes, so you could go to 71 characters (or even 72 if you don't manage strings with a terminating zero).

Actual implementations will have a limit which depends on what the implementer believed and enforced in all of the above. All decent implementations will allow you at least 50 characters. Beyond that, support is not guaranteed. If you need to support passwords longer than 50 characters, you can add a preliminary hashing step, as discussed in this question (but, of course, this means that you no longer compute "the" bcrypt, but a local variant, so interoperability goes down the drain).

Edit: it has been pointed out to me that although, from a cryptographer's point of view, the article is the ultimate reference, this is not necessarily how the designers thought about it. The "original" implementation could process up to 72 bytes. Depending on your stance on formalism, you may claim that the implementation is right and the article is wrong. Anyway, such is the current state of things that my advice remains valid: if you keep under 50 characters, you will be fine everywhere. (Of course it would have been better if the algorithm did not have a length limitation in the first place.)
