Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PSDI Army
yii2
Commits
40635024
Commit
40635024
authored
Jun 27, 2014
by
Paul Klimov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Option `Security::deriveKeyStrategy` added
parent
84659629
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
75 additions
and
2 deletions
+75
-2
Security.php
framework/base/Security.php
+44
-1
SecurityTest.php
tests/unit/framework/base/SecurityTest.php
+31
-1
No files found.
framework/base/Security.php
View file @
40635024
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
*/
*/
namespace
yii\base
;
namespace
yii\base
;
use
yii\helpers\StringHelper
;
use
yii\helpers\StringHelper
;
use
Yii
;
use
Yii
;
...
@@ -34,22 +35,33 @@ class Security extends Component
...
@@ -34,22 +35,33 @@ class Security extends Component
* @var integer crypt block size in bytes.
* @var integer crypt block size in bytes.
* For AES-128, AES-192, block size is 128-bit (16 bytes).
* For AES-128, AES-192, block size is 128-bit (16 bytes).
* For AES-256, block size is 256-bit (32 bytes).
* For AES-256, block size is 256-bit (32 bytes).
* Recommended value: 32
*/
*/
public
$cryptBlockSize
=
32
;
public
$cryptBlockSize
=
32
;
/**
/**
* @var integer crypt key size in bytes.
* @var integer crypt key size in bytes.
* For AES-192, key size is 192-bit (24 bytes).
* For AES-192, key size is 192-bit (24 bytes).
* For AES-256, key size is 256-bit (32 bytes).
* For AES-256, key size is 256-bit (32 bytes).
* Recommended value: 32
*/
*/
public
$cryptKeySize
=
32
;
public
$cryptKeySize
=
32
;
/**
/**
* @var string derivation hash algorithm name.
* @var string derivation hash algorithm name.
* Recommended value: 'sha256'
*/
*/
public
$derivationHash
=
'sha256'
;
public
$derivationHash
=
'sha256'
;
/**
/**
* @var integer derivation iterations count.
* @var integer derivation iterations count.
* Recommended value: 1000000
*/
*/
public
$derivationIterations
=
1000000
;
public
$derivationIterations
=
1000000
;
/**
* @var string strategy, which should be used to derive a key for encryption.
* Available strategies:
* - 'pbkdf2' - PBKDF2 key derivation, this option is recommended, but it requires PHP version >= 5.5.0
* - 'hmac' - HMAC hash key derivation.
*/
public
$deriveKeyStrategy
=
'hmac'
;
/**
/**
* Encrypts data.
* Encrypts data.
...
@@ -131,20 +143,51 @@ class Security extends Component
...
@@ -131,20 +143,51 @@ class Security extends Component
* Derives a key from the given password (PBKDF2).
* Derives a key from the given password (PBKDF2).
* @param string $password the source password
* @param string $password the source password
* @param string $salt the random salt
* @param string $salt the random salt
* @throws InvalidConfigException if unsupported derive key strategy is configured.
* @return string the derived key
* @return string the derived key
*/
*/
protected
function
deriveKey
(
$password
,
$salt
)
protected
function
deriveKey
(
$password
,
$salt
)
{
{
switch
(
$this
->
deriveKeyStrategy
)
{
case
'pbkdf2'
:
return
$this
->
deriveKeyPbkdf2
(
$password
,
$salt
);
case
'hmac'
:
return
$this
->
deriveKeyHmac
(
$password
,
$salt
);
default
:
throw
new
InvalidConfigException
(
"Unknown Derive key strategy '
{
$this
->
deriveKeyStrategy
}
'"
);
}
}
/**
* Derives a key from the given password using PBKDF2.
* @param string $password the source password
* @param string $salt the random salt
* @throws InvalidConfigException if environment does not allows PBKDF2.
* @return string the derived key
*/
protected
function
deriveKeyPbkdf2
(
$password
,
$salt
)
{
if
(
function_exists
(
'hash_pbkdf2'
))
{
if
(
function_exists
(
'hash_pbkdf2'
))
{
return
hash_pbkdf2
(
$this
->
derivationHash
,
$password
,
$salt
,
$this
->
derivationIterations
,
$this
->
cryptKeySize
,
true
);
return
hash_pbkdf2
(
$this
->
derivationHash
,
$password
,
$salt
,
$this
->
derivationIterations
,
$this
->
cryptKeySize
,
true
);
}
else
{
throw
new
InvalidConfigException
(
'Derive key strategy "pbkdf2" requires PHP >= 5.5.0, either upgrade your environment or use another strategy.'
);
}
}
}
/**
* Derives a key from the given password using HMAC.
* @param string $password the source password
* @param string $salt the random salt
* @return string the derived key
*/
protected
function
deriveKeyHmac
(
$password
,
$salt
)
{
$hmac
=
hash_hmac
(
$this
->
derivationHash
,
$salt
.
pack
(
'N'
,
1
),
$password
,
true
);
$hmac
=
hash_hmac
(
$this
->
derivationHash
,
$salt
.
pack
(
'N'
,
1
),
$password
,
true
);
$xorsum
=
$hmac
;
$xorsum
=
$hmac
;
for
(
$i
=
1
;
$i
<
$this
->
derivationIterations
;
$i
++
)
{
for
(
$i
=
1
;
$i
<
$this
->
derivationIterations
;
$i
++
)
{
$hmac
=
hash_hmac
(
$this
->
derivationHash
,
$hmac
,
$password
,
true
);
$hmac
=
hash_hmac
(
$this
->
derivationHash
,
$hmac
,
$password
,
true
);
$xorsum
^=
$hmac
;
$xorsum
^=
$hmac
;
}
}
return
substr
(
$xorsum
,
0
,
$this
->
cryptKeySize
);
return
substr
(
$xorsum
,
0
,
$this
->
cryptKeySize
);
}
}
...
...
tests/unit/framework/base/SecurityTest.php
View file @
40635024
...
@@ -48,8 +48,38 @@ class SecurityTest extends TestCase
...
@@ -48,8 +48,38 @@ class SecurityTest extends TestCase
$this
->
assertFalse
(
$this
->
security
->
validateData
(
$hashedData
,
$key
));
$this
->
assertFalse
(
$this
->
security
->
validateData
(
$hashedData
,
$key
));
}
}
public
function
testEncrypt
()
/**
* Data provider for [[testEncrypt()]]
* @return array test data
*/
public
function
dataProviderEncrypt
()
{
{
return
[
[
'hmac'
,
false
],
[
'pbkdf2'
,
!
function_exists
(
'hash_pbkdf2'
)
],
];
}
/**
* @dataProvider dataProviderEncrypt
*
* @param string $deriveKeyStrategy
* @param boolean $isSkipped
*/
public
function
testEncrypt
(
$deriveKeyStrategy
,
$isSkipped
)
{
if
(
$isSkipped
)
{
$this
->
markTestSkipped
(
"Unable to test '
{
$deriveKeyStrategy
}
' derive key strategy"
);
return
;
}
$this
->
security
->
deriveKeyStrategy
=
$deriveKeyStrategy
;
$data
=
'known data'
;
$data
=
'known data'
;
$key
=
'secret'
;
$key
=
'secret'
;
$encryptedData
=
$this
->
security
->
encrypt
(
$data
,
$key
);
$encryptedData
=
$this
->
security
->
encrypt
(
$data
,
$key
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment