First, MD5 has other problems besides fast hashing speeds, including collision vulnerabilities.
Once computers become faster, then these will be no better than md5.
So I wonder, is it even possible to have a hash function that is
secure, irrespective of the time it takes to execute?
No, a hash function itself could always be cracked using a sufficiently fast computer ( sufficiently fast being the ambiguous silver bullet). However, implementations of hashing algorithms can address this.
As an example, bcrypt provides mechanisms to address the increase in computation speed.
bcrypt uses the concept of rounds to calculate hashes. For example, bcrypt will hash your password with a salt and a number of rounds:
bcrypt("password","salt",10000)
Note: As pointed out by
darkhogg, the rounds parameter isn't actually submitted to bcrypt. Instead a work factor is sent. The difference being that what is sent is actually a number N which is the exponent used to calculate the rounds. So although 10,000 is used here as an example for the number of rounds, the actual work unit you would need to supply to get 10,000 rounds would be much smaller.
hashes the combined salt and password 10,000 times before storing the hash, the salt and the number of rounds. So suppose at the initial time of implementation 10,000 rounds of hashing takes .02 seconds. A year after the initial implementation, you notice that 10,000 rounds only takes .01 seconds, or half the time. You can change the rounds to 20,000. The next time a user logs in, their hash will be computed with 10,000 rounds to authenticate, but the hash will be stored with 20,000 rounds, for future authentication.