Is randomly generating passwords from an assortment of dictionary words cryptographically secure?
First, there is no such concept as a cryptographically secure password. The aim of a password is to be hard to guess for an attacker and how hard it should be to guess depends on how the password is used: if the account is locked after three failed attempts the password can be more weak compared to when an attacker can try an unlimited number of passwords or when the attacker has access to the hashed passwords.
In your case you create a password from randomly choosing 5 words from a set of 10k words. Assuming that the attacker knows your dictionary (not unlikely because your requirement is easy to remember words) and the way the password is constructed from the dictionary this means that there are (10^4)^5 = 10^20 variants. This is similar to guessing 20 digits or a password with 12..13 random alpha-numeric mixed-case characters. Such passwords are usually considered secure enough for most purposes.
As for the storage of the password: don't invent your own method but use methods proven to be good. For details see How to securely hash passwords? In the current form I would consider the chosen method weak because you are using only 100 iterations with a hash function which is designed to be fast. Just for comparison: PBKDF2 recommended at least 1000 iterations in 2000 already and LastPass used 100.000 iterations for server side hashing in 2011. Fortunately you kind of make up for the weaker password storage by having more complex passwords.
It seems to me that your calculations are correct. Even though, please consider the following weaknesses:
- An attacker can and will sign up for your service with multiple (a LOT of) accounts. From there, it is trivial to create a close-to-original word list. So assume the attacker knows the word list.
- The attacker will also test your password length limitations. As described here, minimum password length of 12 character is a good hint to an attacker that consecutive dictionary words will be used, thus reducing the search space.
- The actual word list makes a difference too. Consider a scenario where your word list consists of an amount of longer than 8 characters long words, and your maximum password length is, say 30. This means the attacker can safely assume that no password will be constructed with 4 consecutive 8 character words. Similar to this, many assumptions can exist according to your choice of word list. So another consideration that I think you've missed is word length entropy.
- Lastly, the fact that you are supplying your clients with a secure and easy-to-remember password generator means that they will use it. So the attacker can also safely assume that all but the most security-aware will use your word list and you password generator.
Despite all of that, I think that what you are proposing is secure. Even when considering all of the above, the resulting search space is still huge.
These are all the problems/assumptions that I found in your description that may decrease the security of your password generator. For your consideration.
Building off of MiaoHatola's answer:
By MiaoHatola's first point, your attacker could narrow down the list and know both dictionaries(the one with short words and the other with 5-letter words). You said your short word list had 994 entries. They have a 1/994 chance of getting the short word on the first try. Now, let's say that you use a list of 10,000 common 5 letter words. These fractions apply:
1/994 * 1/10000 * 1/9999 * 1/9998 * 1/9997
This problem illustrates the combined chances of guessing everything on the first try, assuming they know your word lists.
That is a 1 in 9,934,037,100,000,000,000 chance of guessing just the words, not the order of the words. Factor in the order, and you get quite a high number. My calculator doesn't count that high.
This number doesn't include the possiblity of what MiaoHatola mentioned in their third point because you said you don't have a maximum length. One more thing:
Instead of randomly choosing just 5 words every time, why not randomize that number too? Throw in an extra 7 letter word every once in a while. Maybe include a 2 digit number at the end. Try making the attacker guess. That significantly increases your security. At this point, you could leave the hashed passwords unguarded, because the sheer amount of possibilities is overwhelming. So to answer your question, yes. This increases security. By a lot.