How can I improve a password generation scheme based on a shared secret and URL? I currently use the following method to generate a different password on every website I have to login:

password = SHA1 ( mainPassword . domainName . number )


where . stands for concatenation.

Here are my questions:


Is this secure enough?
I mean, if somebody knows my algorithm and one or many passwords, could he find easily one of my other passwords? Up until now, most people I contacted believe it is true, but I didn't get any real strong certitude.
(Related to question 1) When one of my passwords is compromised, I just increment the number. Is this enough?
Now, as many people suggested, SHA-1 can be a bit too weak and many proposed to use bcrypt or even better scrypt. But, as I understand these two algorithms, it is more about encrypting than hashing. Is it secure to use the following passwords?

SHA1( SHA1( … SHA1( str ) … ))



Here is my reasoning:


It is difficult to retrieve str, knowing sha1(str).
I hope that to retrieve str knowing sha1(sha1(str)) one must do twice of the work.
Therefore retrieving str from sha1n(str) should be n times as difficult than to retrieve sha1(str). 


I am almost sure there won't be any proof of this. But could I consider this method safe enough?

The problem is just to have a very good algorithm similar to bcrypt or scrypt for hashes without the nightmare of finding a correct implementation in all languages I used to implement this (JavaScript, Objective-C, shell script using openssl).
password = sha1 ( mainPassword . domainName . number )
  Is this secure enough?


Answer is no. Let me explain. The only part that is really unknown in the above is mainPassword. The rest can easily be guessed by a hacker. If your original password is weak (not many characters, no digits, no specials characters), the number of combinations to test is small enough for brute force attack (i.e., testing them all). sha1 is not going to help. You are also vulnerable to collision attacks (google it for more information). 

You need to learn about salting and stretching. Use a sufficiently large random number too when you salt-and-strech. Make sure you stretch with enough rounds. Salt and stretch only works if the mainPassword is good enough in the first place.


  could he find easily one of my other password?


If you use a random when salting and stretching, it makes it much harder to guess another password from a known password.


  When one of my password is compromised, I just increment the number. Is it enough?


Absolutely not. It is very easy for the hacker to increase the number too. You really need to use salt-and-strechting with another random number.


  sha1( sha1( ... sha1( str ) ... ))


Not helping when used like that (again, learn about salting and stretching). If you are uncomfortable with SHA1, use SHA256 (or SHA512) as the hash function.

EDIT


  How to keep secret the salt in an open source project? The only other
  way is to make the user choose the salt which seems to be exactly the
  to ask for a longer password. Am I wrong?


Hiding the salt is not absolutely necessary. You could also include a timestamp in the salt-and-stretching. It would require you to perform extra rounds on the server side with the timestamp. If the timestamp is too old, refuse the log on.

EDIT2

To be complete. You can implement something like that:


User picks a password. 
A = any public random;
FOR 1 TO 1000 (or more) hash = SHA( A || hash ); with user pwd
Store hash on server.
Logon -> Server picks a new large random R and sends it to client with authentication
Let t = current time;
User verifies authentication for received R.
User computes FOR 1 TO 1000 (or more) hash = SHA( A || hash ); with entered pwd
Then, FOR 1 TO 1000 (or more) hash = SHA( R || SHA( hash || t) );
Send hash, R, t to server
Server check t is ok (for replay)
Server computes FOR 1 TO 1000 (or more) SHA( R || SHA( stored_hash || t) ); 
Server checks computed against received, and eventually validates logon.


It will kill many attack venues, but it is impossible to eliminate them all.

EDIT II

Sorry, there is an issue with step 8 (and 11), this step needs to be performed 1000 times (i.e., or whatever the number of salt-and-stretch iteration you need) too, or it does not make sense to iterate 1000 in step 7 in the first place.