Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Nextcloud
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Monitor
Service Desk
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
TeDomum
Nextcloud
Commits
0d651f10
Unverified
Commit
0d651f10
authored
5 years ago
by
Roeland Jago Douma
Browse files
Options
Downloads
Patches
Plain Diff
Allow selecting the hashing algorithm
Signed-off-by:
Roeland Jago Douma
<
roeland@famdouma.nl
>
parent
4503cff5
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
config/config.sample.php
+10
-0
10 additions, 0 deletions
config/config.sample.php
lib/private/Security/Hasher.php
+27
-11
27 additions, 11 deletions
lib/private/Security/Hasher.php
tests/lib/Security/HasherTest.php
+63
-2
63 additions, 2 deletions
tests/lib/Security/HasherTest.php
with
100 additions
and
13 deletions
config/config.sample.php
+
10
−
0
View file @
0d651f10
...
...
@@ -1435,6 +1435,16 @@ $CONFIG = array(
/**
* Hashing
*/
/**
* By default Nextcloud will use the Argon2 password hashing if available.
* However if for whatever reason you want to stick with the PASSWORD_DEFAULT
* of your php version. Then set the setting to true.
*/
'hashing_default_password'
=>
false
,
/**
*
* Nextcloud uses the Argon2 algorithm (with PHP >= 7.2) to create hashes by its
* own and exposes its configuration options as following. More information can
...
...
This diff is collapsed.
Click to expand it.
lib/private/Security/Hasher.php
+
27
−
11
View file @
0d651f10
...
...
@@ -92,11 +92,13 @@ class Hasher implements IHasher {
* @return string Hash of the message with appended version parameter
*/
public
function
hash
(
string
$message
):
string
{
if
(
\defined
(
'PASSWORD_ARGON2I'
))
{
$alg
=
$this
->
getPrefferedAlgorithm
();
if
(
\defined
(
'PASSWORD_ARGON2I'
)
&&
$alg
===
PASSWORD_ARGON2I
)
{
return
2
.
'|'
.
password_hash
(
$message
,
PASSWORD_ARGON2I
,
$this
->
options
);
}
else
{
return
1
.
'|'
.
password_hash
(
$message
,
PASSWORD_BCRYPT
,
$this
->
options
);
}
return
1
.
'|'
.
password_hash
(
$message
,
PASSWORD_BCRYPT
,
$this
->
options
);
}
/**
...
...
@@ -147,12 +149,7 @@ class Hasher implements IHasher {
*/
protected
function
verifyHashV1
(
string
$message
,
string
$hash
,
&
$newHash
=
null
)
:
bool
{
if
(
password_verify
(
$message
,
$hash
))
{
$algo
=
PASSWORD_BCRYPT
;
if
(
\defined
(
'PASSWORD_ARGON2I'
))
{
$algo
=
PASSWORD_ARGON2I
;
}
if
(
password_needs_rehash
(
$hash
,
$algo
,
$this
->
options
))
{
if
(
$this
->
needsRehash
(
$hash
))
{
$newHash
=
$this
->
hash
(
$message
);
}
return
true
;
...
...
@@ -170,7 +167,7 @@ class Hasher implements IHasher {
*/
protected
function
verifyHashV2
(
string
$message
,
string
$hash
,
&
$newHash
=
null
)
:
bool
{
if
(
password_verify
(
$message
,
$hash
))
{
if
(
password_
needs
_r
ehash
(
$hash
,
PASSWORD_ARGON2I
,
$this
->
options
))
{
if
(
$this
->
needs
R
ehash
(
$hash
))
{
$newHash
=
$this
->
hash
(
$message
);
}
return
true
;
...
...
@@ -199,8 +196,27 @@ class Hasher implements IHasher {
return
$this
->
legacyHashVerify
(
$message
,
$hash
,
$newHash
);
}
return
false
;
}
private
function
needsRehash
(
string
$hash
):
bool
{
$algorithm
=
$this
->
getPrefferedAlgorithm
();
return
password_needs_rehash
(
$hash
,
$algorithm
,
$this
->
options
);
}
private
function
getPrefferedAlgorithm
()
{
$default
=
PASSWORD_BCRYPT
;
if
(
\defined
(
'PASSWORD_ARGON2I'
))
{
$default
=
PASSWORD_ARGON2I
;
}
// Check if we should use PASSWORD_DEFAULT
if
(
$this
->
config
->
getSystemValue
(
'hashing_default_password'
,
false
)
===
true
)
{
$default
=
PASSWORD_DEFAULT
;
}
return
$default
;
}
}
This diff is collapsed.
Click to expand it.
tests/lib/Security/HasherTest.php
+
63
−
2
View file @
0d651f10
...
...
@@ -126,8 +126,12 @@ class HasherTest extends \Test\TestCase {
$this
->
config
->
expects
(
$this
->
any
())
->
method
(
'getSystemValue'
)
->
with
(
'passwordsalt'
,
null
)
->
will
(
$this
->
returnValue
(
'6Wow67q1wZQZpUUeI6G2LsWUu4XKx'
));
->
willReturnCallback
(
function
(
$key
,
$default
)
{
if
(
$key
===
'passwordsalt'
)
{
return
'6Wow67q1wZQZpUUeI6G2LsWUu4XKx'
;
}
return
$default
;
});
$result
=
$this
->
hasher
->
verify
(
$password
,
$hash
);
$this
->
assertSame
(
$expected
,
$result
);
...
...
@@ -162,4 +166,61 @@ class HasherTest extends \Test\TestCase {
$this
->
assertFalse
(
password_needs_rehash
(
$relativePath
[
'hash'
],
PASSWORD_ARGON2I
,
[]));
}
public
function
testUsePasswordDefaultArgon2iVerify
()
{
if
(
!
\defined
(
'PASSWORD_ARGON2I'
))
{
$this
->
markTestSkipped
(
'Need ARGON2 support to test ARGON2 hashes'
);
}
$this
->
config
->
method
(
'getSystemValue'
)
->
with
(
'hashing_default_password'
)
->
willReturn
(
true
);
$message
=
'mysecret'
;
$argon2i
=
2
.
'|'
.
password_hash
(
$message
,
PASSWORD_ARGON2I
,
[]);
$newHash
=
null
;
$this
->
assertTrue
(
$this
->
hasher
->
verify
(
$message
,
$argon2i
,
$newHash
));
$this
->
assertNotNull
(
$newHash
);
}
public
function
testDoNotUserPasswordDefaultArgon2iVerify
()
{
if
(
!
\defined
(
'PASSWORD_ARGON2I'
))
{
$this
->
markTestSkipped
(
'Need ARGON2 support to test ARGON2 hashes'
);
}
$this
->
config
->
method
(
'getSystemValue'
)
->
with
(
'hashing_default_password'
)
->
willReturn
(
false
);
$message
=
'mysecret'
;
$argon2i
=
2
.
'|'
.
password_hash
(
$message
,
PASSWORD_ARGON2I
,
[]);
$newHash
=
null
;
$this
->
assertTrue
(
$this
->
hasher
->
verify
(
$message
,
$argon2i
,
$newHash
));
$this
->
assertNull
(
$newHash
);
}
public
function
testHashUsePasswordDefault
()
{
if
(
!
\defined
(
'PASSWORD_ARGON2I'
))
{
$this
->
markTestSkipped
(
'Need ARGON2 support to test ARGON2 hashes'
);
}
$this
->
config
->
method
(
'getSystemValue'
)
->
with
(
'hashing_default_password'
)
->
willReturn
(
true
);
$message
=
'mysecret'
;
$hash
=
$this
->
hasher
->
hash
(
$message
);
$relativePath
=
self
::
invokePrivate
(
$this
->
hasher
,
'splitHash'
,
[
$hash
]);
$this
->
assertSame
(
1
,
$relativePath
[
'version'
]);
$info
=
password_get_info
(
$relativePath
[
'hash'
]);
$this
->
assertEquals
(
PASSWORD_BCRYPT
,
$info
[
'algo'
]);
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment