-
Notifications
You must be signed in to change notification settings - Fork 44
Mechanism
This page introduces encryption mechanism.
- WKeyGen(password, salt) = PBKDF2_SHA512(password, salt, iterations: 1e4)
- SKeyGen(password, salt) = PBKDF2_SHA512(password, salt, iterations: 1e6)
- REDUCED_INFO is a function to drop
one character information
.
- password_0 = REDUCED_INFO(password)
- secret_key = SKeyGen(password_0, WKeyGen(username, JSsalt)))
- confusion_key = WKeyGen(password, secret_key)
- login_signature = WKeyGen(secret_key, username)
- submit login_signature to server for authentication
- User input account and corresponding password into web browser.
- POST
login_signature
to server for authentication. At server side, PBKDF2_SHA3-512 will be used to hashlogin_signature
- Web browser calculate the mapping alphabet which is from SHA512(entry_account_name) and
confusion_key
. - Using the mapping alphabet to map the raw password into a confusion password. Same characters in original password might map to different characters in confusion password to prevent the attackers getting the pattern of your password.
- Using AES256-CBC to encrypt confusion mapped password, as well as account and using
secret_key
as key. - POST each AES256 encrypted account and password entry to server.
- POST
login_signature
to server as authentication. At server side, PBKDF2_SHA3-512 will be used to hashlogin_signature
- Web browser calculate the mapping alphabet which is from SHA512(entry_account_name) and
confusion_key
. - Server retrieve data from database, send back all encrypted strings.
- Using AES256-CBC to decrypt confusion mapped password, as well as account and using
secret_key
as key. - Using the mapping alphabet to map the confusion password into raw password, based on
confusion_key
.
From v9.09, Password Manager supports small binary file storage along with an account. This feature is enabled by default but users might turn it off in funciton/config.php
by setting $FILE_ENABLED = False
. This feature is useful when you want to store a ssh key, a certificate or some small images. However, it should not be used as another dropbox. In current design, file is base64 encoded and stored in database after encryption. If file becomes too large, the performance of the system will be undermined. Thus, we recommend you to keep files stored per entry within 500KiB. Since file part is much larger compared to text part, different design is adopted for files.
- File name is encrypted with
secret_key
as passphrase by AES256. - A random key is generated and encrypted with
secret_key
,file_name
with WKeyGen. This random key is permanently associated with this file. - Data is first encoded with base64 and then encrypted with the random key.
- Encrypted file name, key and data will be uploaded to server.
- Therefore, Data decryption is only related to the random key. If the user changes something, we only need to re-encrypt the random key associated with the data instead of the data itself.
- User input
PIN
- Web browser generates a random
salt
of length 100 and put it in localstorage - web browser send SKeyGen(pin, salt) as
pin_sig
to server (server furture hash thispin_sig
with PBKDF-SHA3) - server receives
pin_sig
and generates an randomserver_key
with length 512 bits, sendserver_key
to web browser - web browser encrypt
secret_key
andconfusion_key
with WKeyGen(PIN
+server_key
, salt) and store them in localstorage.server_key
won't be stored in browser - When login, after inputing
PIN
, web browser send SKeyGen(pin, salt) to server - Server receives
pin_sig
, if it's correct, send backserver_key
, otherwise, increase theerror_try
by 1 - if
error_try
> 3, server delete this PIN record, the user needs to input username/password. - After receiving
server_key
, web browser is able to decryptsecret_key
andconfusion_key
- By using WKeyGen(secret_key, username), web browser gets
login_sig
and it usesusername
in cookie and thislogin_sig
to login.
Suppose attackers can't get the screen access when you use password manager. Let's discuss some worst cases.
If you put reasonable complexity on the login password, this can take several hundred of years.
If you did not enable client-side source file check, you are doomed. So if you can't 100% trust your server (e.g. VPS), you should always enable client-side source file check.
If you enabled client-side source file check, attacker can't change your client-side code without alerting you. But all server side encryption is useless in this case if attacker can change server side code. However, we have strong encryption at client side so you are still safe. (Say attacker will only need 100 years now to hack your password instead of several hundred)
If you didn't set PIN, the attacker can only enumerate possible passwords. If you set PIN, note part of the decryption information is stored at server side and the attacker needs to enumerate your PIN to get the information from server. Enumerating PIN is easier than login password but after 3 failed attempts, the server will permanently delete the information at server side and then PIN becomes useless.
PIN is useless to attacker on this case because he doesn't have access to pin_salt. If he tries to enumerate your password, remember that you did 1e6 rounds of PBKDF2_SHA512 at client side
If you didn't set PIN, you are still safe as your client is useless. Otherwise, attacker can easily (much easier than all above cases) gets your secret key by enumerating your PIN so that SKeyGen(PIN, pin_salt)=pin_sig
. Since PIN is relatively easier, you can suppose attacker will get your data in several hours.
This is a very extreme case and you should notice if it happens.
This design is inherited from several years ago for fail-safe and I don't think it's needed anymore. However, I'll just keep it in case some part of my encryption algorithm has security flaws...
-
confusion_key
contains all information in your login password, part of which is not involved in server-side authentication. - Any information for the above part (I(confusion_key) - I(login_sig)) will not be uploaded to server.
- Using wrong login password you might be able to login (as long as
login_sig
induced is the same with the correct one), but will see incorrect passwords (very different from the correct ones). But the design ofREDUCE_INFO
calculation ensures that incorrect login passwords by mistake won't log you in (for two passwords that generate samelogin_sig
, they are same or different at all letters). So only attackers that enumerate your login passwords might run into this case. - Change the extra information in confusion_key actually changes the pseudo-passwords.
- Except that the user sees completely different passwords on screen, inputing wrong login password that happens to generate the correct
login_sig
won't cause any errors. And since all passwords uses alphabet-based confusion, it's hard to tell whether the password is correct directly. Hopefully you will get alert when the attacker attempts to login to some sites with wrong passwords.
- The login might take around 1 second on modern computer or cellphone. Other than that, user will not notice the time lag caused by encryption / decryption.
- If you feel the Password-Manager is slow, most likely your server side
PBKDF2_ITERATION
is too large. This value can be configured atsrc/function/config.php
- If you are sure the client side crypto is slow, you can adjust the client side PBKDF2 number of iterations in function
SgenerateKeyWithSalt
atsrc/js/common/cryptoWrapper.js
. This is not recommended. Not only you lower the security level, the backup / recovery function will be impacted. That said, when you want to recover your backup, you need this editedcryptoWrapper.js
- Kick out client after sometime of no action (done by JavaScript)
- Kick out client after sometime of no interaction with server (done by server)
- Block account and IP address for certain time after too many error attempts
- Email based two step verification on new device (default is off)
- Configurable global salt.