Search code examples
encryptionpasswordsaescbc-mode

How to encrypt and decrypt on the client that may come from a different device and the server doesn't store any encrypted key?


I am making a password management tool like Lasspass for myself and family to use, but I have encountered some problems in security. After reading LastPass-Technical-Whitepaper, I am very curious about how they do it only on the client side. According to the "Local-Only Encryption Model" they describe, the server only stores the encrypted infomation. Does this mean that they don't store any key or IV or salt for AES decryption on their server side? As far as I know, this may be fine if I encrypt and decrypt on the same device, but I use Lasspass to add a password on the computer, but I can see the password on the mobile phone. How do they decrypt it on the mobile phone? Should the mobile phone have no key and IV and salt for computer-side encryption, isn't it?

I am currently using ASP.NET Core 3.0+React+identityserver

How should the truly secure "Local-Only Encryption Model" be implemented? Could someone give me some direction? Thanks for any help.


Solution

  • first: i don't know about the lastpass implementation, or the paper

    but let's have a look at what we can do...

    let's say we have a server that stores binary data for us, and further, it does so on a per user/account basis...

    what do we need to be able to authorize account functions like "replace data" or "request stored data"?

    we need a task that has to be solved by the client that proofs the client-identity, in other words an operation that can be solved if-and-only-if the client holds a specific secret... this screams for asymetric crypto and/or digital signatures ... keypairs ...

    how could we do this if we have no shared storage to safely store a key and share it between 2 different devices?

    one possible solution is quite simple and starts with... PBKDF2 ... Password Derived Key Derivation Function

    PBKDF2 takes a password, a salt, a parameter for the number of rounds, and gives you... bits... pseudo random bits

    Take your username and hash it ... => a perfect salt...
    Take an arbitrary number like 15000 => your number of rounds (larger numbers slow down the process of calculating -> slowing down bruteforce attacks while you only need to calculate it once every login)
    Take your password => surprise... a password

    run PBKDF2

    seed your favourite CSPRNG (Cryptographically Secure Pseudo Random Number Generator) with a few bytes from the resulting bitstream

    use your favourite CSPRNG to generate a new (RSA,DSA,ECDSA,whatever) keypair ...

    use the key

    this EXACT key pair will be generated EVERY time you run these steps, on any device

    of course this breaks down the security of said keypair to the strength of the secret parameters to PBKDF2, which will be... your password

    but now you have asymetric crypto from a password...

    the server stores the public key ... and just asks the client to decrypt a number (a nonce) together with the request to replace/retrieve the data... being able to decrypt the nonce proofs that the secret key is known to the client

    you can also derive an AES key from the PBKDF2 Stream to encrypt your Password database before you send it to the server ... or to decrypt it once it has been recieved