Discussion:
[go-nuts] Handling Encrypted Passwords/Data
m***@mcrilly.me
2014-11-14 15:42:56 UTC
Permalink
Hello,

As a learning exercise, which I hope will extend into something more
useful, I'm going to write a simple password management RESTful API. I will
further extend on this by writing various clients, including an Android
application, so that I can learn some basic Android development skills. You
know, because it's fun :-)

I also want to be able to have my own "Cloud" based password manager, but
obviously I want to ensure I am handling the raw passwords correctly. From
the persecptive of generating random strings, I don't think I will have any
issues, but it's the handling of the data, like keeping it in RAM, ensuring
plain text versions aren't leaking or present in RAM, etc. Here is a list
of the overarching objectives, for context:

- The remote API code will generate new passwords, storing them in a
SQLite DB;
- The SQLite DB stored passwords will be encrypted, probably using AES;
- Passwords are always generated remotely;
- A master password is used as the secret to the AES crypto;
- A strong HTTPS/TLS certificate will be used for over-the-wire
transport between server and client;
- The SQLite DB, and all related files, will be supported by an
encrypted file system for added protection;

It's a set of simple goals, really. Here are my concerns:

- How do I keep the plain texts as protected as possible? Does Go have a
"protected memory" operation mode, or is this something the underlaying OS
provides? I'm told the Linux kernel can be employed to hold secret keys for
you, helping to protect them from attack?
- How do I go about encrypting the entire SQLite DB? Should I even
bother? Is the non-sensitive metadata worth protecting to that degree?
- Is AES the right algo to use? Obviously I want to use an existing algo;

I know some readers may see this as yet-another-pm, but it's a pet project
that I will enjoy, so please, bare with me on this one!

All help appreciated.

- Mike
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Shawn Milochik
2014-11-14 17:25:15 UTC
Permalink
Never, under any circumstances, allow the encryption key or the plain-text
password to to be available to your password manager server. Anything else
is a complete failure of design. Have a look at how LastPass does it. The
plaintext password is never transferred, nor is the key. All password
generation and encryption is done client-side.

1. A client-side session exists. The password used to log in is hashed with
the user's e-mail address and this is used as the key.
2. A client generates a new password. It is encrypted with that key.
3. The *encrypted password only *is sent to LastPass.

Retrieval:
The client logs in, their password (never leaving their machine) is used to
once again generate the long encryption key. The encrypted password is
retrieved from LastPass and decrypted locally.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
m***@mcrilly.me
2014-11-17 15:34:55 UTC
Permalink
This is everyone's opinion on the matter, so it's the route I will take.
Thank you for the clarity.

Now I need some opinions on the start of a GCM wrapping library I have
started. Here is a Gist of the file that handles the encryption of data.
There is a main function in there, as well as it being in the main package,
so you can throw this in a file and fire it up.

https://gist.github.com/mrcrilly/492e519e0e3513e42e2a

All opinions welcome.

- M
Post by Shawn Milochik
Never, under any circumstances, allow the encryption key or the plain-text
password to to be available to your password manager server. Anything else
is a complete failure of design. Have a look at how LastPass does it. The
plaintext password is never transferred, nor is the key. All password
generation and encryption is done client-side.
1. A client-side session exists. The password used to log in is hashed
with the user's e-mail address and this is used as the key.
2. A client generates a new password. It is encrypted with that key.
3. The *encrypted password only *is sent to LastPass.
The client logs in, their password (never leaving their machine) is used
to once again generate the long encryption key. The encrypted password is
retrieved from LastPass and decrypted locally.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
James Bardin
2014-11-17 15:48:25 UTC
Permalink
I understand if you want to do this as an academic exercise, but if you
don't need the crypto to interoperate with something external, the
crypto/nacl package is very simple and is my first choice in Go right now:

https://godoc.org/golang.org/x/crypto/nacl/secretbox
Post by m***@mcrilly.me
This is everyone's opinion on the matter, so it's the route I will take.
Thank you for the clarity.
Now I need some opinions on the start of a GCM wrapping library I have
started. Here is a Gist of the file that handles the encryption of data.
There is a main function in there, as well as it being in the main package,
so you can throw this in a file and fire it up.
https://gist.github.com/mrcrilly/492e519e0e3513e42e2a
All opinions welcome.
- M
Post by Shawn Milochik
Never, under any circumstances, allow the encryption key or the
plain-text password to to be available to your password manager server.
Anything else is a complete failure of design. Have a look at how LastPass
does it. The plaintext password is never transferred, nor is the key. All
password generation and encryption is done client-side.
1. A client-side session exists. The password used to log in is hashed
with the user's e-mail address and this is used as the key.
2. A client generates a new password. It is encrypted with that key.
3. The *encrypted password only *is sent to LastPass.
The client logs in, their password (never leaving their machine) is used
to once again generate the long encryption key. The encrypted password is
retrieved from LastPass and decrypted locally.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Lars Seipel
2014-11-15 14:20:01 UTC
Permalink
Post by m***@mcrilly.me
- The remote API code will generate new passwords, storing them in a
SQLite DB;
- The SQLite DB stored passwords will be encrypted, probably using AES;
- Passwords are always generated remotely;
I'd also question that design choice. Why generate passwords on the
remote server? It's so much more that could go wrong that way. Generate
passwords locally and only ever transmit the encrypted password store
over the wire. Make sure the cleartext never leaves the machine.
Post by m***@mcrilly.me
- Is AES the right algo to use? Obviously I want to use an existing algo;
No, it's not. It might be part of the solution, though. Read some book
on applied cryptography and try to understand why "use AES" is not in
itself a sufficient answer to the question of "how do I encrypt this
file".

Maybe take a look at the go.crypto subrepo as it offers some
abstractions that might be suited to what you want to do.

Also, I recommend reading Ross Anderson's Security Engineering. It's
freely available online for some time. It describes many of the things
to keep in mind when working with crypto stuff. It also has some
nice-to-read trivia.

Find it here:
http://www.cl.cam.ac.uk/~rja14/book.html

Lars
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...