> "This package will install io.js v1.0.0 and npm v2.1.18 into /usr/local/. The binary /usr/local/bin/iojs will also be symlinked as /usr/local/bin/node."
I've had a totally opposite experience. Stripe has been amazing for us. Clean API, good documentation, a slick dashboard, responsive support team, etc.
Processing credit card transactions is a hard enough problem that it rarely makes sense for any non-payments company to do it themselves. Dropbox and Airbnb use Braintree (a Stripe competitor) for payments, and they are both much bigger than Kickstarter. Even Twitter and Facebook have been known to use Stripe for various products, and they are obviously much bigger than Kickstarter as well.
In the future, I imagine almost every site will use HTTPS—maybe browsers will even refuse to connect over plain HTTP. Then this kind of attack won't be possible.
You don't have to memorize them, though. If your master key is "bananas" and it didn't work, try "bananas2", "bananas3", etc. But you don't need to remember them all—because they're all essentially the same.
Hopefully this happens infrequently enough that it's a non-issue anyway.
2^16 rounds of SHA-256 might not be "ultra slow" but it's certainly not as bad as you make it seem. If you read the analysis in the article, it would take many years to crack a random password with this hash function. It's unfair to say I "ignored" that requirement.
> SuperGenPass uses a one-way hash algorithm (base-64 MD5) to generate passwords. Specifically, it concatenates the master password and the domain name of the Web site (masterpassword:domain.com), hashes the result at least ten times (and until it satisfies the generated password requirements), and cuts the result to the desired length.
Yikes! MD5 is known to be broken, and 10 rounds of hashing is no defense against brute force attacks. Hashpass uses SHA-256 (not broken) and does 2^16 rounds of hashing.
It's true that changing the master key is a pain, but you don't have to do it for every website at once. Though it might be hard during the transition to remember which sites have the updated key.
Not having a database certainly has its downsides.
Re usability: I've been using it for a couple days now, and I find it pretty tolerable. It's nice to not have to memorize a new password when I sign up for something. I did change my master key once; it took about 5 minutes to update all my passwords. If you only do that once every few months or once a year, it's not so bad.
A salt is random bits added to a password. Hashpass prefers to be stateless, so it just asks the user to pick a strong password (possibly by adding random bits like a salt). It puts more trust in the user, which obviously comes at a price.
Re key strengthening: Agreed, but only salt-less schemes will work in this stateless model. Unfortunately they are few.
> Finally. What happens when the password requires to have upper case, symbols, x number of digits, min or max number of characters... If you think about it, some websites have conflicting requirements.
Addressed this in the article: "Some websites have certain requirements on passwords, e.g., at least one number and one capital letter. A simple way to meet such requirements is to append something like A9! to the generated password (and remember you did that)."
Yes, you should not use this unless you are willing to memorize a strong secret key. There are warnings in the article, but perhaps it could have used a few more.
This is one of those "only use it if you know what you're doing" things.
This is not a new technique. In addition to the Stanford paper, there are several other implementations mentioned in these comments. It's a compromise, not a mistake. It is better to memorize one strong password than a dozen weak ones.
This isn't custom crypto. It's a well-known hash function that serves as a filter, transforming the passwords you would otherwise enter directly into a website's login form. It is no less secure than typing in passwords by hand.
Correct, there is no salt. A dictionary attack will uncover common passwords. It's crucial to pick a strong secret key. That's the price you pay for using a stateless password manager.
However, the gigazillion rounds are not for nothing. That is the defense against brute force attacks, which could otherwise crack passwords even if they are random.
"If a generated password is ever compromised, you don’t need to memorize a whole new secret key and update all of your passwords. For that service only, just add an incrementing index to your secret key. For example, if your key was bananas, just use bananas2. If you can’t remember which iteration of your secret key you used for a particular service, simply try them all in order."
In particular, you don't have to use the same secret key for all websites. It's okay to slightly modify one if that password is compromised.
Really? I've never seen any synchronization code (e.g., locks) in JavaScript. If multiple threads can execute async tasks in parallel, doesn't that mean JavaScript needs synchronization primitives? Most JS code I've seen in the wild relies implicitly on the single-threaded assumption—that only one callback (for example) will run at a time.
SICP isn't a research publication—it's a pedagogical work. It's been very valuable as a textbook for CS students, but I don't think it contributed any significant ideas to the field of PL.
All of these are valid points except 1. Node's async IO is one of its strengths. Contrast with Rails, for example, where the standard practice for concurrency is to spawn multiple processes (or, less commonly, threads). How many Rails processes can you fit on one machine? 5-10? Node can handle thousands of concurrent connections, all on a single thread. And when you hit those limits, you can always continue scaling with multiple processes like you would with Rails.
Doing CPU-bound computation in your application server is an anti-pattern. IO-bound computation, however, is where Node excels.
The thing to realize is that pre-emptive multitasking is costly. It is convenient for the programmer (the programmer doesn't need to worry about blocking and locking up the rest of the program), but it comes at a cost. Lightweight "green" threads, or equivalently, Node's evented dispatch mechanism, are a much more efficient use of the CPU. For applications composed of short-lived computations (e.g., < 1ms), it doesn't make sense to interrupt them and context switch. It's more performant to let them complete and then switch. You just have to make sure you aren't doing any CPU-intensive computations in the app server—which you probably shouldn't be doing anyway.
The downside of Node's approach is callback hell. And that's why we have Go.
Just re-read this and realized it's unclear: when I said O(n) time, I meant linear in the length of the URL to be parsed. The point is that with this technique, it doesn't matter how many routes there are.
That's right. Typical routing regexes will not use backreferences, so that's not really an issue here. However, most routes do have parameters implemented as capture groups (which, I believe, is also not technically a feature of regular expressions). One simple solution would be to use a big regex (the union of all the routes) to determine which route it is (in O(n) time), and then once you know the route, use another regex to parse the parameters in the URL. So each route lookup requires 2 regex matches rather than N.
I've had better experience with Angular, though some of the complaints apply to Angular too (e.g., silent errors in templates). Recently I started using Facebook's React framework, and so far it's worked well for me. You'll probably end up writing more code than you would in Angular/Ember, but that's because React is only a view framework (so it frees you up to use vanilla JavaScript for other things, like ajax, routing, etc.). React is also much faster than Angular because of its virtual DOM patching technique.
But my favorite part of React so far is that view logic is grouped together with the views. This goes against the "best practice" of separating views and logic, but I think it makes navigating the codebase easier. You want to learn everything about how some custom view widget works? It's all in one file, rather than spread across app/assets/javascripts/widget.js and app/views/widgets/widget.html.erb. No directory hopping needed to learn how the widget works.
> "This package will install io.js v1.0.0 and npm v2.1.18 into /usr/local/. The binary /usr/local/bin/iojs will also be symlinked as /usr/local/bin/node."