Skip to content

Instantly share code, notes, and snippets.



Last active Oct 18, 2016
What would you like to do?
"How Dropbox securely stores your passwords" in terrible, insecure, horrible GoLang (GoLang is not terrible, my code is).

+++ WARNING +++

This is just a little test. It should NOT be used for your passwords unless you know what you're doing. I (on the other hand) do NOT know what I'm doing, so please, don't trust this code.

+++ WARNING +++

How Dropbox securely stores your passwords

From :

The Challenge

All I wanted to do was try and copy what Dropbox did for their passwords, in Go. Whether this is correct or not, I have no idea. It was a coding challenge only.

But ... I'd love it if you could fork this and make it better and more correct. Ping me at @andychilton.

Example Runs

$ go run pw.go 
2016/10/03 22:48:09 Hashed = 6bd54875a5abdc46ab6b871e7271b1174239422f55416965364b76364f61687439485762616f4863545a6b31763734556d6d55715276496267744f53

$ go run pw.go 
2016/10/03 23:01:04 Hashed = 439903360a1292949e1eb7e29d8b9d8d724953655a4344506d446e55754d59435556314962494f6e2f6e664932382f797a71726d71354b6f58494875

$ go run pw.go 
2016/10/03 23:01:07 Hashed = 8955d598ed168fa7e6df501cc30dd80e6a53566d36425955506f4534755667525152574f46674f734d6c3262764d3358416462337743495679426869


Andrew Chilton. (Yes, I know my website is currently not serving on https. Go figure.)


I know this is Dropbox's idea but they blogged about it publicly, so I tried it. Everything I've put here is the following license:


package main
import (
// Dropbox performs password hashing, bcrypting, and encryption as described in
func Dropbox(pw string, key []byte) ([]byte, error) {
// SHA512
h := sha512.New()
io.WriteString(h, pw)
sha512Bytes := h.Sum(nil)
// log.Printf("SHA512 = %x\n", sha512Bytes)
// now base64 encode this, since bcrypt stops at null bytes
base64 := hex.EncodeToString(sha512Bytes)
// now bcrypt it
bcryptBytes, err := bcrypt.GenerateFromPassword([]byte(base64), 10)
if err != nil {
return nil, err
// log.Printf("bcrypt = %x\n", bcryptBytes)
// AES256
cipher, err := aes.NewCipher(key)
if err != nil {
return nil, err
cipher.Encrypt(bcryptBytes, bcryptBytes)
// log.Printf("aes256 = %x\n", bcryptBytes)
// all good
return bcryptBytes, nil
func main() {
// This is the silliest password ever, choose something better.
password := "password"
// This is the silliest key ever, choose something better.
// ToDo: I'm not sure if this is of the correct length for AES256?
key := []byte("ABCDEFGHIJKLMNOP")
// hash the password
bytes, err := Dropbox(password, key)
if err != nil {
log.Printf("Hashed = %x\n", bytes)

This comment has been minimized.

Copy link

@devd devd commented Oct 3, 2016


For ease of elucidation, the blogpost elided a couple of details. We base64 encode the output of SHA512 since bcrypt will stop at a null byte. We also use a versioned encryption scheme to help with key rotation etc. Also, we use an authenticated encryption scheme over plain AES (so something like seal from aes_gcm package is closer to what we do). These might be worth adding here, IMO. thanks!


This comment has been minimized.

Copy link
Owner Author

@chilts chilts commented Oct 18, 2016

Cool, thanks @devd. I have base64 encoded the output of the sha512. I'm still grokking a few things related to what you mean by the AES stuff, seal and ars_gcm. :)

I've been thinking about the versioned scheme. I guess it could be something like a type which knows about every scheme you've ever done, and essentially loops through each to check if the password is correct. Also, the same type, if given a password always encodes for the latest version. By version, that not only includes how, but also valid keys too. I dunno ... am just thinking out loud.


This comment has been minimized.

Copy link
Owner Author

@chilts chilts commented Oct 18, 2016

And I've been thinking about how to have multiple password schemes and upgrading if needed. Looks like this package does that qutie well :

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment