mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-22 09:35:08 -07:00
[Security] Add challenge-response auth with scrypt verifiers and stop storing plaintext passwords
Challenge-response authentication: the client derives a scrypt verifier (RFC 7914, EVP_PBE_scrypt, N=32768, r=8, p=1) and authenticates with HMAC-SHA256(key, nonce), so neither the password nor its hash is transmitted. The stored format becomes "$scrypt$<n>$<r>$<p>$<salt>$<verifier>" and Response_PasswordSalt now carries the cost parameters. Strict servers only accept scrypt verifiers; legacy accounts are migrated after a successful login. Fix #344 for challenge-response servers: a saved profile stores the derived verifier under the password key instead of the plaintext password. The connect dialog loads it without revealing it, autoconnect passes it through, the change-password dialog no longer prefills the old password field with it, and the client only persists the verifier when "Save password" is checked. Took 3 minutes Took 1 minute Took 10 seconds Took 7 minutes
This commit is contained in:
parent
d6fbfb32a1
commit
7a3067d4a8
33 changed files with 834 additions and 30 deletions
|
|
@ -25,7 +25,8 @@ void FeatureSet::initalizeFeatureList(QMap<QString, bool> &_featureList)
|
|||
_featureList.insert("idle_client", false);
|
||||
_featureList.insert("forgot_password", false);
|
||||
_featureList.insert("websocket", false);
|
||||
// featureList.insert("hashed_password_login", false);
|
||||
_featureList.insert("hashed_password_login", false);
|
||||
_featureList.insert("challenge_response_auth", false);
|
||||
// These are temp to force users onto a newer client
|
||||
_featureList.insert("2.7.0_min_version", false);
|
||||
_featureList.insert("2.8.0_min_version", false);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ message Event_ServerIdentification {
|
|||
enum ServerOptions {
|
||||
NoOptions = 0;
|
||||
SupportsPasswordHash = 1;
|
||||
SupportsChallengeResponseAuth = 2;
|
||||
}
|
||||
optional string server_name = 1;
|
||||
optional string server_version = 2;
|
||||
|
|
|
|||
|
|
@ -6,4 +6,14 @@ message Response_PasswordSalt {
|
|||
optional Response_PasswordSalt ext = 1017;
|
||||
}
|
||||
optional string password_salt = 1;
|
||||
// scrypt cost parameters for password_salt. Absent/zero for legacy accounts.
|
||||
optional int32 n = 2;
|
||||
optional int32 r = 3;
|
||||
optional int32 p = 4;
|
||||
// Server-generated challenge. When present the client must authenticate
|
||||
// with a challenge-response instead of transmitting the password hash.
|
||||
optional bytes nonce = 5;
|
||||
// True when the account still uses the legacy password format and should
|
||||
// be migrated to the scrypt format after a successful login.
|
||||
optional bool needs_migration = 6;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ message SessionCommand {
|
|||
FORGOT_PASSWORD_CHALLENGE = 1023;
|
||||
REQUEST_PASSWORD_SALT = 1024;
|
||||
SET_CARD_ART_PARAMS = 1025;
|
||||
SUBMIT_PASSWORD_VERIFIER = 1026;
|
||||
REPLAY_LIST = 1100;
|
||||
REPLAY_DOWNLOAD = 1101;
|
||||
REPLAY_MODIFY_MATCH = 1102;
|
||||
|
|
@ -223,3 +224,14 @@ message Command_SetCardArtParams {
|
|||
optional double vertical_offset = 5;
|
||||
optional double zoom = 6;
|
||||
}
|
||||
|
||||
// Client uploads the new password verifier to migrate a legacy account
|
||||
// after a successful challenge-response login. Idempotent; only applies
|
||||
// to accounts still using the legacy password format.
|
||||
message Command_SubmitPasswordVerifier {
|
||||
extend SessionCommand {
|
||||
optional Command_SubmitPasswordVerifier ext = 1026;
|
||||
}
|
||||
// Full verifier string to store, e.g. "$scrypt$32768$8$1$<salt>$<verifier>"
|
||||
required string password_verifier = 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue