My book on password authentication is out

I’m super excited to announce that my book, Password authentication for web and mobile apps, is out! I have a lot more to say about why I decided to write it and what the writing and publishing process was in future blog posts. Meanwhile, if you’re a developer who wants to understand password authentication and implement it for your web site or your app, please check it out:


My book on password authentication is now in the Kindle Store

Password Authentication for Web and Mobile Apps is now available in Amazon Kindle Store. If you like the convenience of buying your ebooks there, go get a copy! Don’t forget to leave a review after reading it.


🇺🇸 Amazon US (and the rest of the world)
🇬🇧 Amazon UK
🇨🇦 Amazon CA
🇦🇺 Amazon AU
🇮🇳 Amazon IN
🇩🇪 Amazon DE
🇫🇷 Amazon FR
🇪🇸 Amazon ES
🇮🇹 Amazon IT
🇳🇱 Amazon NL
🇯🇵 Amazon JP
🇧🇷 Amazon BR
🇲🇽 Amazon MX

The book continues to be available from my website. In fact, you and I get better value if you buy it directly from me: in addition to the MOBI version for Kindle, you’ll also get an EPUB that you can read on any device and a nicely formatted PDF version. You can pay with a credit card, PayPal, or even with your Amazon account (in some countries). And I get a bigger cut of what you paid 🙂


Improving storage of password-encrypted secrets in end-to-end encrypted apps

Many apps with client-side encryption that use passwords derive both encryption and server authentication keys from them.

One such example is Bitwarden, a cross-platform password manager. It uses PBKDF2-HMAC-SHA-256 with 100,000 rounds to derive an encryption key from a user’s master password, and an additional 1-round PBKDF2 to derive a server authentication key from that key. Bitwarden additionally hashes the authentication key on the server with 100,000-iteration PBKDF2 “for a total of 200,001 iterations by default”. In this post I’ll show you that these additional iterations for the server-side hashing are useless if the database is leaked, and the actual strength of the hashing is only as good as the client-side PBKDF2 iterations plus an AES decryption and one HMAC. I will also show you how to fix this.


Why password peppering in Devise library for Rails is not secure

Devise is a popular authentication solution for Ruby on Rails. Most web apps need some kind of authentication system for user accounts and Devise allows adding one with just a few lines of code. This is great for security — if all the developers need to do is to plug a third-party library, there are fewer chances to make a mistake. This, however, requires that the library itself is implemented correctly, which is, unfortunately, not the case for many of them.

Security Tools

How to use Chrome securely

  1. Install uBlock Origin extension. (If you’re not from US, check its options to turn on ad block lists for your country)
  2. Do not install any other extensions ever! (exceptions: 1Password, Google Arts & Culture).
  3. Create separate “people” for different activities: e.g. home, work, browsing sketchy websites. (Click on avatar → Manage People.)
  4. If you want to turn on sync, set up encryption passphrase. It’s a separate passphrase from your Google account — your sync data will be encrypted locally with it before hitting Google servers.
  5. Disable saving/auto fill of passwords, payment, and addresses. (

That is all (for now).


Copywriting gems from a hundred-year-old Sears catalog

Sears, Roebuck & Company, which filed for bankruptcy last year, started its life as a mail-order firm in 1892, the Amazon of its time.

The early success of the company is often attributed to its co-founder’s copywriting skills. Richard Warren Sears was a railroad station agent in Minnesota when in 1886 his station received an unsolicited shipment of gold watches for a local jeweler, who refused it. Sears saw an opportunity and agreed with the wholesaler to sell them himself, in six months making a profit larger than his railroad salary. He then founded the company to sell watches and jewelry via advertisements in publications and by mailing flyers, and later started a catalog, for which Sears wrote every line of copy. He retired in 1908, but the tradition of good copywriting continued, helping the company become the largest retailer in the world.


Synchronizing Android and macOS with Nextcloud

Google and Microsoft are further along on the technology, but haven’t quite figured it out yet – tie all of our products together, so we further lock customers into our ecosystem.

Steve Jobs

We may suspend or stop providing our services to you if you do not comply with our terms or policies or if we are investigating suspected misconduct.


I recently set up my own Nextcloud server to synchronize contacts, calendars and files between my laptop and Android smartphone without intermediaries, as an experiment. Here are the client tools I used.


How to disregard business trends to find your niche

NearlyFreeSpeech.NET is a sharing hosting provider with a pretty unique approach. The amount of fucks they give about trends, be it business models popular in industry or cloud stuff or “fanatical support™ with customer champions”, is close to zero.


Securing Go web applications

There are lots of security-related things to keep in mind when writing a web application, as the Web is a place full of danger: cross-site scripting (XSS), cross-site request forgery (CSRF), clickjacking, brute forcing, spam and so on.

Go gets many things right by default: for example, templates from the standard library make it hard to accidentally introduce XSS vulnerabilities. But what about other attacks? Fortunately, there are a few open source Go packages that can help us.


Mac developers: don’t use AQDataExtensions

AQDataExtensions is an NSData category developed in 2005 by Lucas Newman and distributed with AquaticPrime framework which “allows for easily encrypting and decrypting NSData objects with AES/Rijndael (i.e. the Advanced Encryption Standard)“.

The methods are:

- (NSData*)dataEncryptedWithPassword:(NSString*)password
- (NSData*)dataDecryptedWithPassword:(NSString*)password

Unfortunately, AQDataExtensions has the following weaknesses:

  1. Weak key derivation function.
  2. No authentication.
  3. Weak random numbers.