Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5771)

Unified Diff: chrome/browser/signin/local_auth.cc

Issue 862103002: Only store leading 13 bits of password hash. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Pre-review check Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/signin/local_auth.cc
diff --git a/chrome/browser/signin/local_auth.cc b/chrome/browser/signin/local_auth.cc
index 7748898f8e7a2c08decd9f033792208cb5f62c9c..c1db0ad86d205ccdb31d74d54341bda19c8f45e6 100644
--- a/chrome/browser/signin/local_auth.cc
+++ b/chrome/browser/signin/local_auth.cc
@@ -31,6 +31,11 @@ const unsigned kHash1Bits = 256;
const unsigned kHash1Bytes = kHash1Bits / 8;
const unsigned kHash1IterationCount = 100000;
+// Store 13 bits to provide pin-like security (8192 possible values), without
+// providing a complete oracle for the user's GAIA password.
+const unsigned kHash1StoredBits = 13;
bcwhite 2015/01/21 21:04:40 "Hash2" This is storage method #2. Use the same
Mike Lerman 2015/01/27 21:02:26 Done.
+const unsigned kHash1StoredBytes = (kHash1StoredBits + 7) / 8;
+
std::string CreateSecurePasswordHash(const std::string& salt,
const std::string& password,
char encoding) {
@@ -131,6 +136,7 @@ void SetLocalAuthCredentials(size_t info_index,
std::string password_hash = CreateSecurePasswordHash(
salt_str, password, kHash1Encoding);
DCHECK_EQ(kHash1Bytes, password_hash.length());
+ password_hash = TruncateStringByBits(password_hash, kHash1StoredBits);
// Group all fields into a single record for storage;
std::string record;
@@ -158,6 +164,7 @@ bool ValidateLocalAuthCredentials(size_t info_index,
std::string record;
char encoding;
+ bool update_stored_credential = false;
ProfileInfoCache& info =
g_browser_process->profile_manager()->GetProfileInfoCache();
@@ -175,21 +182,33 @@ bool ValidateLocalAuthCredentials(size_t info_index,
size_t password_length;
if (encoding == '1') {
bcwhite 2015/01/21 21:04:40 The handling of v1 encoding should never change.
Mike Lerman 2015/01/27 21:02:26 Done.
- // Validate correct length; extract salt and password hash.
- if (record.length() != 2 * kHash1Bytes)
- return false;
+ // Extract salt.
std::string salt_str(record.data(), kHash1Bytes);
password_saved = record.data() + kHash1Bytes;
- password_hash = CreateSecurePasswordHash(salt_str, password, encoding);
+ // Extract password hash.
+ if (record.length() == 2 * kHash1Bytes) {
+ password_hash = CreateSecurePasswordHash(salt_str, password, encoding);
+ password_length = kHash1Bytes;
+ update_stored_credential = true;
+ } else if (record.length() == kHash1Bytes + kHash1StoredBytes) {
+ password_hash = CreateSecurePasswordHash(salt_str, password, encoding);
jww 2015/01/22 21:48:18 Given bcwhite's comment about never changing the h
bcwhite 2015/01/23 01:28:38 I didn't pass an encoding version to "create" beca
jww 2015/01/26 18:31:51 CreateSecurePasswordHash() is used to validate the
bcwhite 2015/01/27 18:02:25 I guess I always imagined that a new method would
Mike Lerman 2015/01/27 21:02:26 Ok, CreateSecurePasswordHash will call Truncate.
+ password_hash = TruncateStringByBits(password_hash, kHash1StoredBits);
+ password_length = kHash1StoredBytes;
+ } else {
+ // Unknown record length.
+ return false;
+ }
password_check = password_hash.data();
- password_length = kHash1Bytes;
} else {
- // unknown encoding
+ // Unknown encoding.
return false;
}
- return crypto::SecureMemEqual(password_saved, password_check,
- password_length);
+ bool passwords_match = crypto::SecureMemEqual(
+ password_saved, password_check, password_length);
+ if (passwords_match && update_stored_credential)
+ SetLocalAuthCredentials(info_index, password);
+ return passwords_match;
}
bool ValidateLocalAuthCredentials(const Profile* profile,
@@ -198,4 +217,19 @@ bool ValidateLocalAuthCredentials(const Profile* profile,
password);
}
+std::string TruncateStringByBits(const std::string& str,
bcwhite 2015/01/21 21:04:40 Rest of the file calls upward so put this function
Mike Lerman 2015/01/27 21:02:26 Done.
+ const size_t len_bits) {
+ if (len_bits % 8 == 0)
+ return str.substr(0, len_bits / 8);
+
+ // The initial truncation copies whole bytes
+ int number_bytes = (len_bits + 7) / 8;
+ std::string truncated_string = str.substr(0, number_bytes);
+
+ // Keep the prescribed number of bits from the last byte.
+ unsigned last_char_bitmask = pow(2, len_bits % 8) - 1;
bcwhite 2015/01/21 21:04:40 pow(2, len_bits % 8) == (1 << (len_bits % 8))
Mike Lerman 2015/01/27 21:02:26 Done.
+ truncated_string[number_bytes - 1] &= last_char_bitmask;
+ return truncated_string;
+}
+
} // namespace chrome

Powered by Google App Engine
This is Rietveld 408576698