類別 yii\base\Security
繼承關係 | yii\base\Security » yii\base\Component » yii\base\BaseObject |
---|---|
實作介面 | yii\base\Configurable |
可用版本 | 2.0 |
原始碼 | https://github.com/yiisoft/yii2/blob/master/framework/base/Security.php |
Security 提供了一組方法來處理常見的安全性相關任務。
特別是,Security 支援以下功能
- 加密/解密:encryptByKey()、decryptByKey()、encryptByPassword() 和 decryptByPassword()
- 使用標準演算法的金鑰衍生:pbkdf2() 和 hkdf()
- 資料竄改預防:hashData() 和 validateData()
- 密碼驗證:generatePasswordHash() 和 validatePassword()
注意:此類別需要在 Windows 上使用 'OpenSSL' PHP 擴充套件來進行隨機金鑰/字串產生,並在所有平台上進行加密/解密。為了達到最高的安全性,建議使用 PHP 版本 >= 5.5.0。
有關 Security 的更多詳細資訊和使用方法,請參閱關於安全性的指南文章。
公開屬性
屬性 | 類型 | 描述 | 定義於 |
---|---|---|---|
$allowedCiphers | 陣列[] | 每個支援的 OpenSSL 密碼的區塊大小和金鑰大小的查找表。 | yii\base\Security |
$authKeyInfo | 字串 | 訊息驗證金鑰衍生的 HKDF info 值。 | yii\base\Security |
$behaviors | yii\base\Behavior[] | 附加到此元件的行為列表。 | yii\base\Component |
$cipher | 字串 | 用於加密和解密的密碼。 | yii\base\Security |
$derivationIterations | 整數 | 衍生迭代次數。 | yii\base\Security |
$kdfHash | 字串 | 金鑰衍生的雜湊演算法。 | yii\base\Security |
$macHash | 字串 | 訊息驗證的雜湊演算法。 | yii\base\Security |
$passwordHashCost | 整數 | 用於密碼雜湊的預設成本。 | yii\base\Security |
$passwordHashStrategy | 字串 | 應該用於產生密碼雜湊的策略。 | yii\base\Security |
公開方法
保護方法
方法 | 描述 | 定義於 |
---|---|---|
decrypt() | 解密資料。 | yii\base\Security |
encrypt() | 加密資料。 | yii\base\Security |
generateSalt() | 產生可用於產生密碼雜湊的 salt。 | yii\base\Security |
shouldUseLibreSSL() | yii\base\Security |
屬性詳細資訊
每個支援的 OpenSSL 密碼的區塊大小和金鑰大小的查找表。
在每個元素中,金鑰是 OpenSSL 支援的密碼之一 (@see openssl_get_cipher_methods())。值是一個包含兩個整數的陣列,第一個是密碼的區塊大小(以位元組為單位),第二個是金鑰大小(以位元組為單位)。
警告:我們推薦的所有 OpenSSL 密碼都在預設值中,即 CBC 模式的 AES。
注意:Yii 的加密協定對密碼金鑰、HMAC 簽章金鑰和金鑰衍生 salt 使用相同的大小。
'AES-128-CBC' => [
16,
16,
],
'AES-192-CBC' => [
16,
24,
],
'AES-256-CBC' => [
16,
32,
],
]
訊息驗證金鑰衍生的 HKDF info 值。
另請參閱 hkdf()。
金鑰衍生的雜湊演算法。建議使用 sha256、sha384 或 sha512。
另請參閱 hash_algos()。
訊息驗證的雜湊演算法。建議使用 sha256、sha384 或 sha512。
另請參閱 hash_algos()。
用於密碼雜湊的預設成本。允許值介於 4 到 31 之間。
另請參閱 generatePasswordHash()。
password_hash()
,否則使用 crypt()
。
應該用於產生密碼雜湊的策略。可用的策略
- 'password_hash' - 使用帶有 PASSWORD_DEFAULT 演算法的 PHP
password_hash()
函數。建議使用此選項,但它需要 PHP 版本 >= 5.5.0 - 'crypt' - 使用 PHP
crypt()
函數。
方法詳細資訊
定義於: yii\base\Component::__call()
呼叫未定義為類別方法的具名方法。
此方法將檢查是否有任何附加的行為具有具名方法,如果可用,將執行它。
請勿直接呼叫此方法,因為它是 PHP 魔術方法,當調用未知方法時,將會隱式呼叫它。
public mixed __call ( $name, $params ) | ||
$name | 字串 |
方法名稱 |
$params | 陣列 |
方法參數 |
return | mixed |
方法傳回值 |
---|---|---|
throws | yii\base\UnknownMethodException |
當呼叫未知方法時 |
public function __call($name, $params)
{
$this->ensureBehaviors();
foreach ($this->_behaviors as $object) {
if ($object->hasMethod($name)) {
return call_user_func_array([$object, $name], $params);
}
}
throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
}
public void __clone ( ) |
public function __clone()
{
$this->_events = [];
$this->_eventWildcards = [];
$this->_behaviors = null;
}
定義於: yii\base\BaseObject::__construct()
建構子。
預設實作執行兩件事
- 使用給定的組態
$config
初始化物件。 - 呼叫 init()。
如果在子類別中覆寫此方法,建議
- 建構子的最後一個參數是組態陣列,例如此處的
$config
。 - 在建構子的結尾呼叫父實作。
public void __construct ( $config = [] ) | ||
$config | 陣列 |
將用於初始化物件屬性的名稱-值對 |
public function __construct($config = [])
{
if (!empty($config)) {
Yii::configure($this, $config);
}
$this->init();
}
定義於: yii\base\Component::__get()
傳回元件屬性的值。
此方法將依以下順序檢查並採取相應措施
- getter 定義的屬性:傳回 getter 結果
- 行為的屬性:傳回行為屬性值
請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 $value = $component->property;
時,將會隱式呼叫它。
另請參閱 __set()。
public mixed __get ( $name ) | ||
$name | 字串 |
屬性名稱 |
return | mixed |
屬性值或行為屬性的值 |
---|---|---|
throws | yii\base\UnknownPropertyException |
如果未定義屬性 |
throws | yii\base\InvalidCallException |
如果屬性是唯寫的。 |
public function __get($name)
{
$getter = 'get' . $name;
if (method_exists($this, $getter)) {
// read property, e.g. getName()
return $this->$getter();
}
// behavior property
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canGetProperty($name)) {
return $behavior->$name;
}
}
if (method_exists($this, 'set' . $name)) {
throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
}
throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
}
定義於: yii\base\Component::__isset()
檢查屬性是否已設定,即已定義且非 null。
此方法將依以下順序檢查並採取相應措施
- setter 定義的屬性:傳回屬性是否已設定
- 行為的屬性:傳回屬性是否已設定
- 為不存在的屬性傳回
false
請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 isset($component->property)
時,將會隱式呼叫它。
public boolean __isset ( $name ) | ||
$name | 字串 |
屬性名稱或事件名稱 |
return | boolean |
具名屬性是否已設定 |
---|
public function __isset($name)
{
$getter = 'get' . $name;
if (method_exists($this, $getter)) {
return $this->$getter() !== null;
}
// behavior property
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canGetProperty($name)) {
return $behavior->$name !== null;
}
}
return false;
}
定義於: yii\base\Component::__set()
設定元件屬性的值。
此方法將依以下順序檢查並採取相應措施
- setter 定義的屬性:設定屬性值
- 格式為 "on xyz" 的事件:將處理常式附加到事件 "xyz"
- 格式為 "as xyz" 的行為:附加名為 "xyz" 的行為
- 行為的屬性:設定行為屬性值
請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 $component->property = $value;
時,將會隱式呼叫它。
另請參閱 __get()。
public void __set ( $name, $value ) | ||
$name | 字串 |
屬性名稱或事件名稱 |
$value | mixed |
屬性值 |
throws | yii\base\UnknownPropertyException |
如果未定義屬性 |
---|---|---|
throws | yii\base\InvalidCallException |
如果屬性是唯讀的。 |
public function __set($name, $value)
{
$setter = 'set' . $name;
if (method_exists($this, $setter)) {
// set property
$this->$setter($value);
return;
} elseif (strncmp($name, 'on ', 3) === 0) {
// on event: attach event handler
$this->on(trim(substr($name, 3)), $value);
return;
} elseif (strncmp($name, 'as ', 3) === 0) {
// as behavior: attach behavior
$name = trim(substr($name, 3));
$this->attachBehavior($name, $value instanceof Behavior ? $value : Yii::createObject($value));
return;
}
// behavior property
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canSetProperty($name)) {
$behavior->$name = $value;
return;
}
}
if (method_exists($this, 'get' . $name)) {
throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
}
throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
}
定義於: yii\base\Component::__unset()
將元件屬性設定為 null。
此方法將依以下順序檢查並採取相應措施
- setter 定義的屬性:將屬性值設定為 null
- 行為的屬性:將屬性值設定為 null
請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 unset($component->property)
時,將會隱式呼叫它。
public void __unset ( $name ) | ||
$name | 字串 |
屬性名稱 |
throws | yii\base\InvalidCallException |
如果屬性是唯讀的。 |
---|
public function __unset($name)
{
$setter = 'set' . $name;
if (method_exists($this, $setter)) {
$this->$setter(null);
return;
}
// behavior property
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canSetProperty($name)) {
$behavior->$name = null;
return;
}
}
throw new InvalidCallException('Unsetting an unknown or read-only property: ' . get_class($this) . '::' . $name);
}
定義於: yii\base\Component::attachBehavior()
將行為附加到此元件。
此方法將根據給定的組態建立行為物件。之後,將透過呼叫 yii\base\Behavior::attach() 方法將行為物件附加到此元件。
另請參閱 detachBehavior()。
public yii\base\Behavior attachBehavior ( $name, $behavior ) | ||
$name | 字串 |
$name |
行為的名稱。 | $behavior |
|
return | yii\base\Behavior |
將傳遞給 Yii::createObject() 以建立行為物件的物件組態陣列。 |
---|
public function attachBehavior($name, $behavior)
{
$this->ensureBehaviors();
return $this->attachBehaviorInternal($name, $behavior);
}
將行為列表附加到元件。
定義於: yii\base\Component::attachBehaviors()
每個行為都由其名稱索引,並且應該是 yii\base\Behavior 物件、指定行為類別的字串或用於建立行為的組態陣列。
另請參閱 attachBehavior()。 | ||
$behaviors | 陣列 |
public void attachBehaviors ( $behaviors ) |
public function attachBehaviors($behaviors)
{
$this->ensureBehaviors();
foreach ($behaviors as $name => $behavior) {
$this->attachBehaviorInternal($name, $behavior);
}
}
傳回此元件應表現為的行為列表。
定義於: yii\base\Component::behaviors()
子類別可以覆寫此方法,以指定它們想要表現為的行為。
'behaviorName' => [
'class' => 'BehaviorClass',
'property1' => 'value1',
'property2' => 'value2',
]
此方法的傳回值應為行為物件或組態的陣列,並以行為名稱索引。行為組態可以是指定行為類別的字串,也可以是以下結構的陣列
請注意,行為類別必須從 yii\base\Behavior 擴充。行為可以使用名稱或匿名方式附加。當名稱用作陣列金鑰時,使用此名稱,稍後可以使用 getBehavior() 檢索行為,或使用 detachBehavior() 分離行為。匿名行為無法檢索或分離。
在此方法中宣告的行為將自動(按需)附加到元件。 | ||
return | 陣列 |
---|
public function behaviors()
{
return [];
}
Defined in: yii\base\Component::canGetProperty()
傳回一個值,指示是否可以讀取屬性。
屬性可被讀取,如果
- 類別具有與指定名稱相關聯的 getter 方法(在這種情況下,屬性名稱不區分大小寫);
- 類別具有帶有指定名稱的成員變數(當
$checkVars
為 true 時); - 附加的行為具有給定名稱的可讀屬性(當
$checkBehaviors
為 true 時)。
另請參閱 canSetProperty()。
public(公有) boolean canGetProperty ( $name, $checkVars = true, $checkBehaviors = true ) | ||
$name | 字串 |
屬性名稱 |
$checkVars | boolean |
是否將成員變數視為屬性 |
$checkBehaviors | boolean |
是否將行為的屬性視為此元件的屬性 |
return | boolean |
屬性是否可以被讀取 |
---|
public function canGetProperty($name, $checkVars = true, $checkBehaviors = true)
{
if (method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name)) {
return true;
} elseif ($checkBehaviors) {
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canGetProperty($name, $checkVars)) {
return true;
}
}
}
return false;
}
Defined in: yii\base\Component::canSetProperty()
傳回一個值,指示是否可以設定屬性。
屬性可被寫入,如果
- 類別具有與指定名稱相關聯的 setter 方法(在這種情況下,屬性名稱不區分大小寫);
- 類別具有帶有指定名稱的成員變數(當
$checkVars
為 true 時); - 附加的行為具有給定名稱的可寫入屬性(當
$checkBehaviors
為 true 時)。
另請參閱 canGetProperty()。
public(公有) boolean canSetProperty ( $name, $checkVars = true, $checkBehaviors = true ) | ||
$name | 字串 |
屬性名稱 |
$checkVars | boolean |
是否將成員變數視為屬性 |
$checkBehaviors | boolean |
是否將行為的屬性視為此元件的屬性 |
return | boolean |
屬性是否可以被寫入 |
---|
public function canSetProperty($name, $checkVars = true, $checkBehaviors = true)
{
if (method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name)) {
return true;
} elseif ($checkBehaviors) {
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canSetProperty($name, $checkVars)) {
return true;
}
}
}
return false;
}
::class
。
Defined in: yii\base\BaseObject::className()
傳回此類別的完整限定名稱。
public static(公有靜態) string className ( ) | ||
return | 字串 |
此類別的完整限定名稱。 |
---|
public static function className()
{
return get_called_class();
}
使用定時攻擊抵抗方法執行字串比較。
public(公有) boolean compareString ( $expected, $actual ) | ||
$expected | 字串 |
要比較的字串。 |
$actual | 字串 |
使用者提供的字串。 |
return | boolean |
字串是否相等。 |
---|
public function compareString($expected, $actual)
{
if (!is_string($expected)) {
throw new InvalidArgumentException('Expected expected value to be a string, ' . gettype($expected) . ' given.');
}
if (!is_string($actual)) {
throw new InvalidArgumentException('Expected actual value to be a string, ' . gettype($actual) . ' given.');
}
if (function_exists('hash_equals')) {
return hash_equals($expected, $actual);
}
$expected .= "\0";
$actual .= "\0";
$expectedLength = StringHelper::byteLength($expected);
$actualLength = StringHelper::byteLength($actual);
$diff = $expectedLength - $actualLength;
for ($i = 0; $i < $actualLength; $i++) {
$diff |= (ord($actual[$i]) ^ ord($expected[$i % $expectedLength]));
}
return $diff === 0;
}
解密資料。
另請參閱 encrypt()。
protected(保護) boolean|string decrypt ( $data, $passwordBased, $secret, $info ) | ||
$data | 字串 |
要解密的加密資料。 |
$passwordBased | boolean |
設定為 true 以使用基於密碼的金鑰衍生 |
$secret | 字串 |
解密密碼或金鑰 |
$info | string|null |
上下文/應用程式特定資訊,@see encrypt() |
return | boolean|string |
解密後的資料;若驗證失敗則為 false |
---|---|---|
throws | yii\base\InvalidConfigException |
在未載入 OpenSSL 時 |
throws | yii\base\Exception |
在 OpenSSL 錯誤時 |
protected function decrypt($data, $passwordBased, $secret, $info)
{
if (!extension_loaded('openssl')) {
throw new InvalidConfigException('Encryption requires the OpenSSL PHP extension');
}
if (!isset($this->allowedCiphers[$this->cipher][0], $this->allowedCiphers[$this->cipher][1])) {
throw new InvalidConfigException($this->cipher . ' is not an allowed cipher');
}
list($blockSize, $keySize) = $this->allowedCiphers[$this->cipher];
$keySalt = StringHelper::byteSubstr($data, 0, $keySize);
if ($passwordBased) {
$key = $this->pbkdf2($this->kdfHash, $secret, $keySalt, $this->derivationIterations, $keySize);
} else {
$key = $this->hkdf($this->kdfHash, $secret, $keySalt, $info, $keySize);
}
$authKey = $this->hkdf($this->kdfHash, $key, null, $this->authKeyInfo, $keySize);
$data = $this->validateData(StringHelper::byteSubstr($data, $keySize, null), $authKey);
if ($data === false) {
return false;
}
$iv = StringHelper::byteSubstr($data, 0, $blockSize);
$encrypted = StringHelper::byteSubstr($data, $blockSize, null);
$decrypted = openssl_decrypt($encrypted, $this->cipher, $key, OPENSSL_RAW_DATA, $iv);
if ($decrypted === false) {
throw new \yii\base\Exception('OpenSSL failure on decryption: ' . openssl_error_string());
}
return $decrypted;
}
驗證並解密使用 encryptByKey() 加密的資料。
另請參閱 encryptByKey()。
public(公有) boolean|string decryptByKey ( $data, $inputKey, $info = null ) | ||
$data | 字串 |
要解密的加密資料 |
$inputKey | 字串 |
用於加密和驗證的輸入 |
$info | string|null |
可選的上下文和應用程式特定資訊,請參閱 hkdf() |
return | boolean|string |
解密後的資料;若驗證失敗則為 false |
---|
public function decryptByKey($data, $inputKey, $info = null)
{
return $this->decrypt($data, false, $inputKey, $info);
}
驗證並解密使用 encryptByPassword() 加密的資料。
另請參閱 encryptByPassword()。
public(公有) boolean|string decryptByPassword ( $data, $password ) | ||
$data | 字串 |
要解密的加密資料 |
$password | 字串 |
用於解密的密碼 |
return | boolean|string |
解密後的資料;若驗證失敗則為 false |
---|
public function decryptByPassword($data, $password)
{
return $this->decrypt($data, true, $password, null);
}
public(公有) yii\base\Behavior|null detachBehavior ( $name ) | ||
$name | 字串 |
行為的名稱。 |
return | yii\base\Behavior|null |
已分離的行為。如果行為不存在則為 Null。 |
---|
public function detachBehavior($name)
{
$this->ensureBehaviors();
if (isset($this->_behaviors[$name])) {
$behavior = $this->_behaviors[$name];
unset($this->_behaviors[$name]);
$behavior->detach();
return $behavior;
}
return null;
}
Defined in: yii\base\Component::detachBehaviors()
從元件中分離所有行為。
public(公有) void detachBehaviors ( ) |
public function detachBehaviors()
{
$this->ensureBehaviors();
foreach ($this->_behaviors as $name => $behavior) {
$this->detachBehavior($name);
}
}
加密資料。
另請參閱 decrypt()。
protected(保護) string encrypt ( $data, $passwordBased, $secret, $info ) | ||
$data | 字串 |
要加密的資料 |
$passwordBased | boolean |
設定為 true 以使用基於密碼的金鑰衍生 |
$secret | 字串 |
加密密碼或金鑰 |
$info | string|null |
上下文/應用程式特定資訊,例如使用者 ID。 有關更多詳細資訊,請參閱 RFC 5869 第 3.2 節。 |
return | 字串 |
加密後的資料,以位元組字串表示 |
---|---|---|
throws | yii\base\InvalidConfigException |
在未載入 OpenSSL 時 |
throws | yii\base\Exception |
在 OpenSSL 錯誤時 |
protected function encrypt($data, $passwordBased, $secret, $info)
{
if (!extension_loaded('openssl')) {
throw new InvalidConfigException('Encryption requires the OpenSSL PHP extension');
}
if (!isset($this->allowedCiphers[$this->cipher][0], $this->allowedCiphers[$this->cipher][1])) {
throw new InvalidConfigException($this->cipher . ' is not an allowed cipher');
}
list($blockSize, $keySize) = $this->allowedCiphers[$this->cipher];
$keySalt = $this->generateRandomKey($keySize);
if ($passwordBased) {
$key = $this->pbkdf2($this->kdfHash, $secret, $keySalt, $this->derivationIterations, $keySize);
} else {
$key = $this->hkdf($this->kdfHash, $secret, $keySalt, $info, $keySize);
}
$iv = $this->generateRandomKey($blockSize);
$encrypted = openssl_encrypt($data, $this->cipher, $key, OPENSSL_RAW_DATA, $iv);
if ($encrypted === false) {
throw new \yii\base\Exception('OpenSSL failure on encryption: ' . openssl_error_string());
}
$authKey = $this->hkdf($this->kdfHash, $key, null, $this->authKeyInfo, $keySize);
$hashed = $this->hashData($iv . $encrypted, $authKey);
/*
* Output: [keySalt][MAC][IV][ciphertext]
* - keySalt is KEY_SIZE bytes long
* - MAC: message authentication code, length same as the output of MAC_HASH
* - IV: initialization vector, length $blockSize
*/
return $keySalt . $hashed;
}
使用加密金鑰加密資料。
使用 HKDF 和隨機鹽從輸入金鑰中派生用於加密和驗證的金鑰,相對於 encryptByPassword() 而言非常快速。 輸入金鑰必須是適當的隨機性 - 使用 generateRandomKey() 生成金鑰。 加密資料包含金鑰訊息驗證碼 (MAC),因此無需對輸入或輸出資料進行雜湊處理。
另請參閱
public(公有) string encryptByKey ( $data, $inputKey, $info = null ) | ||
$data | 字串 |
要加密的資料 |
$inputKey | 字串 |
用於加密和驗證的輸入 |
$info | string|null |
可選的上下文和應用程式特定資訊,請參閱 hkdf() |
return | 字串 |
加密後的資料,以位元組字串表示 |
---|
public function encryptByKey($data, $inputKey, $info = null)
{
return $this->encrypt($data, false, $inputKey, $info);
}
使用密碼加密資料。
使用 PBKDF2 和隨機鹽從密碼中派生用於加密和驗證的金鑰,這是有意放慢速度以防止字典攻擊。 使用 encryptByKey() 使用加密金鑰而非密碼快速加密。 金鑰衍生時間由 $derivationIterations 決定,應將其設定為盡可能高的值。 加密資料包含金鑰訊息驗證碼 (MAC),因此無需對輸入或輸出資料進行雜湊處理。 > 注意:盡可能避免使用密碼進行加密。 沒有任何措施可以防止低品質或洩露的密碼。
另請參閱
public(公有) string encryptByPassword ( $data, $password ) | ||
$data | 字串 |
要加密的資料 |
$password | 字串 |
用於加密的密碼 |
return | 字串 |
加密後的資料,以位元組字串表示 |
---|
public function encryptByPassword($data, $password)
{
return $this->encrypt($data, true, $password, null);
}
Defined in: yii\base\Component::ensureBehaviors()
確保在 behaviors() 中宣告的行為已附加到此元件。
public(公有) void ensureBehaviors ( ) |
public function ensureBehaviors()
{
if ($this->_behaviors === null) {
$this->_behaviors = [];
foreach ($this->behaviors() as $name => $behavior) {
$this->attachBehaviorInternal($name, $behavior);
}
}
}
從密碼和隨機 salt 產生安全雜湊。
產生的雜湊值可以儲存在資料庫中。 稍後當需要驗證密碼時,可以獲取雜湊值並傳遞給 validatePassword()。 例如,
// generates the hash (usually done during user registration or when the password is changed)
$hash = Yii::$app->getSecurity()->generatePasswordHash($password);
// ...save $hash in database...
// during login, validate if the password entered is correct using $hash fetched from database
if (Yii::$app->getSecurity()->validatePassword($password, $hash)) {
// password is good
} else {
// password is bad
}
另請參閱 validatePassword()。
public(公有) string generatePasswordHash ( $password, $cost = null ) | ||
$password | 字串 |
要雜湊處理的密碼。 |
$cost | integer|null |
Blowfish 雜湊演算法使用的成本參數。 成本值越高,產生雜湊值以及針對它驗證密碼所需的時間就越長。 因此,更高的成本會減慢暴力破解攻擊的速度。 為了獲得最佳的防範暴力破解攻擊保護,請將其設定為生產伺服器上可容忍的最高值。 計算雜湊值的時間隨著 $cost 每增加一而增加一倍。 |
return | 字串 |
密碼雜湊字串。 當 $passwordHashStrategy 設定為 'crypt' 時,輸出始終為 60 個 ASCII 字元,當設定為 'password_hash' 時,輸出長度可能會在未來版本的 PHP 中增加 (https://php.dev.org.tw/manual/en/function.password-hash.php) |
---|---|---|
throws | yii\base\Exception |
在錯誤的密碼參數或成本參數時。 |
public function generatePasswordHash($password, $cost = null)
{
if ($cost === null) {
$cost = $this->passwordHashCost;
}
if (function_exists('password_hash')) {
/* @noinspection PhpUndefinedConstantInspection */
return password_hash($password, PASSWORD_DEFAULT, ['cost' => $cost]);
}
$salt = $this->generateSalt($cost);
$hash = crypt($password, $salt);
// strlen() is safe since crypt() returns only ascii
if (!is_string($hash) || strlen($hash) !== 60) {
throw new Exception('Unknown error occurred while generating hash.');
}
return $hash;
}
public(公有) string generateRandomKey ( $length = 32 ) | ||
$length | 整數 |
要產生的位元組數 |
return | 字串 |
產生的隨機位元組 |
---|---|---|
throws | yii\base\InvalidArgumentException |
如果指定了錯誤的長度 |
throws | yii\base\Exception |
在失敗時。 |
public function generateRandomKey($length = 32)
{
if (!is_int($length)) {
throw new InvalidArgumentException('First parameter ($length) must be an integer');
}
if ($length < 1) {
throw new InvalidArgumentException('First parameter ($length) must be greater than 0');
}
return random_bytes($length);
}
產生指定長度的隨機字串。
產生的字串符合 [A-Za-z0-9_-]+ 並且對於 URL 編碼是透明的。
public(公有) string generateRandomString ( $length = 32 ) | ||
$length | 整數 |
金鑰的字元長度 |
return | 字串 |
產生的隨機金鑰 |
---|---|---|
throws | yii\base\Exception |
在失敗時。 |
public function generateRandomString($length = 32)
{
if (!is_int($length)) {
throw new InvalidArgumentException('First parameter ($length) must be an integer');
}
if ($length < 1) {
throw new InvalidArgumentException('First parameter ($length) must be greater than 0');
}
$bytes = $this->generateRandomKey($length);
return substr(StringHelper::base64UrlEncode($bytes), 0, $length);
}
產生可用於產生密碼雜湊的 salt。
PHP crypt() 內建函數對於 Blowfish 雜湊演算法,需要特定格式的鹽值字串:"$2a$"、"$2x$" 或 "$2y$"、一個兩位數的成本參數、"$" 和 22 個來自字母表 "./0-9A-Za-z" 的字元。
protected(保護) string generateSalt ( $cost = 13 ) | ||
$cost | 整數 |
成本參數 |
return | 字串 |
隨機鹽值。 |
---|---|---|
throws | yii\base\InvalidArgumentException |
如果成本參數超出 4 到 31 的範圍。 |
protected function generateSalt($cost = 13)
{
$cost = (int) $cost;
if ($cost < 4 || $cost > 31) {
throw new InvalidArgumentException('Cost must be between 4 and 31.');
}
// Get a 20-byte random string
$rand = $this->generateRandomKey(20);
// Form the prefix that specifies Blowfish (bcrypt) algorithm and cost parameter.
$salt = sprintf('$2y$%02d$', $cost);
// Append the random salt data in the required base64 format.
$salt .= str_replace('+', '.', substr(base64_encode($rand), 0, 22));
return $salt;
}
Defined in: yii\base\Component::getBehavior()
傳回具名的行為物件。
public(公有) yii\base\Behavior|null getBehavior ( $name ) | ||
$name | 字串 |
行為名稱 |
return | yii\base\Behavior|null |
行為物件,如果行為不存在則為 null |
---|
public function getBehavior($name)
{
$this->ensureBehaviors();
return isset($this->_behaviors[$name]) ? $this->_behaviors[$name] : null;
}
Defined in: yii\base\Component::getBehaviors()
傳回附加到此元件的所有行為。
public(公有) yii\base\Behavior[] getBehaviors ( ) | ||
return | yii\base\Behavior[] |
附加到此元件的行為列表 |
---|
public function getBehaviors()
{
$this->ensureBehaviors();
return $this->_behaviors;
}
Defined in: yii\base\Component::hasEventHandlers()
傳回一個值,指示是否有名為事件附加任何處理常式。
public(公有) boolean hasEventHandlers ( $name ) | ||
$name | 字串 |
事件名稱 |
return | boolean |
事件是否附加任何處理常式。 |
---|
public function hasEventHandlers($name)
{
$this->ensureBehaviors();
if (!empty($this->_events[$name])) {
return true;
}
foreach ($this->_eventWildcards as $wildcard => $handlers) {
if (!empty($handlers) && StringHelper::matchWildcard($wildcard, $name)) {
return true;
}
}
return Event::hasHandlers($this, $name);
}
Defined in: yii\base\Component::hasMethod()
傳回一個值,指示是否已定義方法。
如果滿足以下條件,則定義了方法:
- 類別具有指定名稱的方法
- 附加的行為具有給定名稱的方法(當
$checkBehaviors
為 true 時)。
public(公有) boolean hasMethod ( $name, $checkBehaviors = true ) | ||
$name | 字串 |
屬性名稱 |
$checkBehaviors | boolean |
是否將行為的方法視為此元件的方法 |
return | boolean |
是否定義了方法 |
---|
public function hasMethod($name, $checkBehaviors = true)
{
if (method_exists($this, $name)) {
return true;
} elseif ($checkBehaviors) {
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->hasMethod($name)) {
return true;
}
}
}
return false;
}
Defined in: yii\base\Component::hasProperty()
傳回一個值,指示是否為此元件定義了屬性。
如果滿足以下條件,則定義了屬性:
- 類別具有與指定名稱相關聯的 getter 或 setter 方法(在這種情況下,屬性名稱不區分大小寫);
- 類別具有帶有指定名稱的成員變數(當
$checkVars
為 true 時); - 附加的行為具有給定名稱的屬性(當
$checkBehaviors
為 true 時)。
另請參閱
public(公有) boolean hasProperty ( $name, $checkVars = true, $checkBehaviors = true ) | ||
$name | 字串 |
屬性名稱 |
$checkVars | boolean |
是否將成員變數視為屬性 |
$checkBehaviors | boolean |
是否將行為的屬性視為此元件的屬性 |
return | boolean |
是否定義了屬性 |
---|
public function hasProperty($name, $checkVars = true, $checkBehaviors = true)
{
return $this->canGetProperty($name, $checkVars, $checkBehaviors) || $this->canSetProperty($name, false, $checkBehaviors);
}
使用金鑰雜湊值作為資料前綴,以便稍後可以檢測到是否被竄改。
無需對 encryptByKey() 或 encryptByPassword() 的輸入或輸出進行雜湊處理,因為這些方法會執行此任務。
另請參閱
public(公有) string hashData ( $data, $key, $rawHash = false ) | ||
$data | 字串 |
要保護的資料 |
$key | 字串 |
用於產生雜湊值的密鑰。 應為安全的加密金鑰。 |
$rawHash | boolean |
產生的雜湊值是否為原始二進制格式。 如果為 false,則會產生小寫十六進制數字。 |
return | 字串 |
以金鑰雜湊值為前綴的資料 |
---|---|---|
throws | yii\base\InvalidConfigException |
當 HMAC 生成失敗時。 |
public function hashData($data, $key, $rawHash = false)
{
$hash = hash_hmac($this->macHash, $data, $key, $rawHash);
if (!$hash) {
throw new InvalidConfigException('Failed to generate HMAC with hash algorithm: ' . $this->macHash);
}
return $hash . $data;
}
使用標準 HKDF 演算法從給定的輸入金鑰衍生金鑰。
實作 RFC 5869 中指定的 HKDF。 建議使用 SHA-2 雜湊演算法之一:sha224、sha256、sha384 或 sha512。
public(公有) string hkdf ( $algo, $inputKey, $salt = null, $info = null, $length = 0 ) | ||
$algo | 字串 |
|
$inputKey | 字串 |
來源金鑰 |
$salt | string|null |
隨機鹽值 |
$info | string|null |
可選資訊,用於將衍生的金鑰材料綁定到應用程式和上下文特定資訊,例如使用者 ID 或 API 版本,請參閱 RFC 5869 |
$length | 整數 |
輸出金鑰的長度(以位元組為單位)。 如果為 0,則輸出金鑰為雜湊演算法輸出的長度。 |
return | 字串 |
衍生的金鑰 |
---|---|---|
throws | yii\base\InvalidArgumentException |
當 HMAC 生成失敗時。 |
public function hkdf($algo, $inputKey, $salt = null, $info = null, $length = 0)
{
if (function_exists('hash_hkdf')) {
$outputKey = hash_hkdf((string)$algo, (string)$inputKey, $length, (string)$info, (string)$salt);
if ($outputKey === false) {
throw new InvalidArgumentException('Invalid parameters to hash_hkdf()');
}
return $outputKey;
}
$test = @hash_hmac($algo, '', '', true);
if (!$test) {
throw new InvalidArgumentException('Failed to generate HMAC with hash algorithm: ' . $algo);
}
$hashLength = StringHelper::byteLength($test);
if (is_string($length) && preg_match('{^\d{1,16}$}', $length)) {
$length = (int) $length;
}
if (!is_int($length) || $length < 0 || $length > 255 * $hashLength) {
throw new InvalidArgumentException('Invalid length');
}
$blocks = $length !== 0 ? ceil($length / $hashLength) : 1;
if ($salt === null) {
$salt = str_repeat("\0", $hashLength);
}
$prKey = hash_hmac($algo, $inputKey, $salt, true);
$hmac = '';
$outputKey = '';
for ($i = 1; $i <= $blocks; $i++) {
$hmac = hash_hmac($algo, $hmac . $info . chr($i), $prKey, true);
$outputKey .= $hmac;
}
if ($length !== 0) {
$outputKey = StringHelper::byteSubstr($outputKey, 0, $length);
}
return $outputKey;
}
public void init ( ) |
public function init()
{
}
遮罩 token 使其不可壓縮。
對令牌應用隨機遮罩,並將使用的遮罩添加到結果前面,使字串始終唯一。 用於通過隨機化每次請求時令牌的輸出方式來緩解 BREACH 攻擊。
public string maskToken ( $token ) | ||
$token | 字串 |
一個未遮罩的令牌。 |
return | 字串 |
一個已遮罩的令牌。 |
---|
public function maskToken($token)
{
// The number of bytes in a mask is always equal to the number of bytes in a token.
$mask = $this->generateRandomKey(StringHelper::byteLength($token));
return StringHelper::base64UrlEncode($mask . ($mask ^ $token));
}
Defined in: yii\base\Component::off()
從此元件分離現有的事件處理常式。
此方法與 on() 相反。
注意:如果為事件名稱傳遞了萬用字元模式,則只會移除使用此萬用字元註冊的處理程序,而使用與此萬用字元匹配的純名稱註冊的處理程序將保留。
另請參閱 on()。
public boolean off ( $name, $handler = null ) | ||
$name | 字串 |
事件名稱 |
$handler | callable|null |
要移除的事件處理程序。 如果為 null,則將移除附加到已命名事件的所有處理程序。 |
return | boolean |
如果找到並分離了處理程序 |
---|
public function off($name, $handler = null)
{
$this->ensureBehaviors();
if (empty($this->_events[$name]) && empty($this->_eventWildcards[$name])) {
return false;
}
if ($handler === null) {
unset($this->_events[$name], $this->_eventWildcards[$name]);
return true;
}
$removed = false;
// plain event names
if (isset($this->_events[$name])) {
foreach ($this->_events[$name] as $i => $event) {
if ($event[0] === $handler) {
unset($this->_events[$name][$i]);
$removed = true;
}
}
if ($removed) {
$this->_events[$name] = array_values($this->_events[$name]);
return true;
}
}
// wildcard event names
if (isset($this->_eventWildcards[$name])) {
foreach ($this->_eventWildcards[$name] as $i => $event) {
if ($event[0] === $handler) {
unset($this->_eventWildcards[$name][$i]);
$removed = true;
}
}
if ($removed) {
$this->_eventWildcards[$name] = array_values($this->_eventWildcards[$name]);
// remove empty wildcards to save future redundant regex checks:
if (empty($this->_eventWildcards[$name])) {
unset($this->_eventWildcards[$name]);
}
}
}
return $removed;
}
Defined in: yii\base\Component::on()
將事件處理常式附加到事件。
事件處理程序必須是有效的 PHP 回呼函數。 以下是一些範例
function ($event) { ... } // anonymous function
[$object, 'handleClick'] // $object->handleClick()
['Page', 'handleClick'] // Page::handleClick()
'handleClick' // global function handleClick()
事件處理程序必須使用以下簽名定義:
function ($event)
其中 $event
是一個 yii\base\Event 物件,其中包含與事件關聯的參數。
自 2.0.14 版本起,您可以將事件名稱指定為萬用字元模式
$component->on('event.group.*', function ($event) {
Yii::trace($event->name . ' is triggered.');
});
另請參閱 off()。
public void on ( $name, $handler, $data = null, $append = true ) | ||
$name | 字串 |
事件名稱 |
$handler | callable |
事件處理程序 |
$data | mixed |
當事件被觸發時,要傳遞給事件處理程序的資料。 當事件處理程序被調用時,可以通過 yii\base\Event::$data 存取此資料。 |
$append | boolean |
是否將新的事件處理程序附加到現有處理程序列表的末尾。 如果為 false,則新的處理程序將插入到現有處理程序列表的開頭。 |
public function on($name, $handler, $data = null, $append = true)
{
$this->ensureBehaviors();
if (strpos($name, '*') !== false) {
if ($append || empty($this->_eventWildcards[$name])) {
$this->_eventWildcards[$name][] = [$handler, $data];
} else {
array_unshift($this->_eventWildcards[$name], [$handler, $data]);
}
return;
}
if ($append || empty($this->_events[$name])) {
$this->_events[$name][] = [$handler, $data];
} else {
array_unshift($this->_events[$name], [$handler, $data]);
}
}
使用標準 PBKDF2 演算法從給定的密碼衍生金鑰。
實作 RFC 2898 第 5.2 節中指定的 HKDF2。 建議使用 SHA-2 雜湊演算法之一:sha224、sha256、sha384 或 sha512。
public string pbkdf2 ( $algo, $password, $salt, $iterations, $length = 0 ) | ||
$algo | 字串 |
|
$password | 字串 |
來源密碼 |
$salt | 字串 |
隨機鹽值 |
$iterations | 整數 |
雜湊演算法的迭代次數。 盡可能設定高一點以阻止字典密碼攻擊。 |
$length | 整數 |
輸出金鑰的長度(以位元組為單位)。 如果為 0,則輸出金鑰為雜湊演算法輸出的長度。 |
return | 字串 |
衍生的金鑰 |
---|---|---|
throws | yii\base\InvalidArgumentException |
當由於給定的參數無效而導致雜湊生成失敗時。 |
public function pbkdf2($algo, $password, $salt, $iterations, $length = 0)
{
if (function_exists('hash_pbkdf2') && PHP_VERSION_ID >= 50500) {
$outputKey = hash_pbkdf2($algo, $password, $salt, $iterations, $length, true);
if ($outputKey === false) {
throw new InvalidArgumentException('Invalid parameters to hash_pbkdf2()');
}
return $outputKey;
}
// todo: is there a nice way to reduce the code repetition in hkdf() and pbkdf2()?
$test = @hash_hmac($algo, '', '', true);
if (!$test) {
throw new InvalidArgumentException('Failed to generate HMAC with hash algorithm: ' . $algo);
}
if (is_string($iterations) && preg_match('{^\d{1,16}$}', $iterations)) {
$iterations = (int) $iterations;
}
if (!is_int($iterations) || $iterations < 1) {
throw new InvalidArgumentException('Invalid iterations');
}
if (is_string($length) && preg_match('{^\d{1,16}$}', $length)) {
$length = (int) $length;
}
if (!is_int($length) || $length < 0) {
throw new InvalidArgumentException('Invalid length');
}
$hashLength = StringHelper::byteLength($test);
$blocks = $length !== 0 ? ceil($length / $hashLength) : 1;
$outputKey = '';
for ($j = 1; $j <= $blocks; $j++) {
$hmac = hash_hmac($algo, $salt . pack('N', $j), $password, true);
$xorsum = $hmac;
for ($i = 1; $i < $iterations; $i++) {
$hmac = hash_hmac($algo, $hmac, $password, true);
$xorsum ^= $hmac;
}
$outputKey .= $xorsum;
}
if ($length !== 0) {
$outputKey = StringHelper::byteSubstr($outputKey, 0, $length);
}
return $outputKey;
}
protected boolean shouldUseLibreSSL ( ) | ||
return | boolean |
是否應使用 LibreSSL。 使用版本為 2.1.5 或更高版本。 |
---|
protected function shouldUseLibreSSL()
{
if ($this->_useLibreSSL === null) {
// Parse OPENSSL_VERSION_TEXT because OPENSSL_VERSION_NUMBER is no use for LibreSSL.
// https://bugs.php.net/bug.php?id=71143
$this->_useLibreSSL = defined('OPENSSL_VERSION_TEXT')
&& preg_match('{^LibreSSL (\d\d?)\.(\d\d?)\.(\d\d?)$}', OPENSSL_VERSION_TEXT, $matches)
&& (10000 * $matches[1]) + (100 * $matches[2]) + $matches[3] >= 20105;
}
return $this->_useLibreSSL;
}
public void trigger ( $name, yii\base\Event $event = null ) | ||
$name | 字串 |
事件名稱 |
$event | yii\base\Event|null |
事件實例。 如果未設定,將建立預設的 yii\base\Event 物件。 |
public function trigger($name, Event $event = null)
{
$this->ensureBehaviors();
$eventHandlers = [];
foreach ($this->_eventWildcards as $wildcard => $handlers) {
if (StringHelper::matchWildcard($wildcard, $name)) {
$eventHandlers[] = $handlers;
}
}
if (!empty($this->_events[$name])) {
$eventHandlers[] = $this->_events[$name];
}
if (!empty($eventHandlers)) {
$eventHandlers = call_user_func_array('array_merge', $eventHandlers);
if ($event === null) {
$event = new Event();
}
if ($event->sender === null) {
$event->sender = $this;
}
$event->handled = false;
$event->name = $name;
foreach ($eventHandlers as $handler) {
$event->data = $handler[1];
call_user_func($handler[0], $event);
// stop further handling if the event is handled
if ($event->handled) {
return;
}
}
}
// invoke class-level attached handlers
Event::trigger($this, $name, $event);
}
取消遮罩先前由 maskToken
遮罩的 token。
public string unmaskToken ( $maskedToken ) | ||
$maskedToken | 字串 |
一個已遮罩的令牌。 |
return | 字串 |
一個未遮罩的令牌,或者在令牌格式無效的情況下為空字串。 |
---|
public function unmaskToken($maskedToken)
{
$decoded = StringHelper::base64UrlDecode($maskedToken);
$length = StringHelper::byteLength($decoded) / 2;
// Check if the masked token has an even length.
if (!is_int($length)) {
return '';
}
return StringHelper::byteSubstr($decoded, $length, $length) ^ StringHelper::byteSubstr($decoded, 0, $length);
}
驗證給定的資料是否被竄改。
另請參閱 hashData()。
public string|false validateData ( $data, $key, $rawHash = false ) | ||
$data | 字串 |
要驗證的資料。 資料必須先前由 hashData() 生成。 |
$key | 字串 |
先前用於在 hashData() 中為資料生成雜湊的密鑰。 函數以查看系統上支援的雜湊演算法。 這必須與傳遞給 hashData() 的值相同,在為資料生成雜湊時。 |
$rawHash | boolean |
這應該採用與您使用 hashData() 生成資料時相同的值。 它指示資料中的雜湊值是否為二進制格式。 如果為 false,則表示雜湊值僅由小寫十六進制數字組成。 將生成十六進制數字。 |
return | string|false |
剝離雜湊的真實資料。 如果資料被篡改,則為 False。 |
---|---|---|
throws | yii\base\InvalidConfigException |
當 HMAC 生成失敗時。 |
public function validateData($data, $key, $rawHash = false)
{
$test = @hash_hmac($this->macHash, '', '', $rawHash);
if (!$test) {
throw new InvalidConfigException('Failed to generate HMAC with hash algorithm: ' . $this->macHash);
}
$hashLength = StringHelper::byteLength($test);
if (StringHelper::byteLength($data) >= $hashLength) {
$hash = StringHelper::byteSubstr($data, 0, $hashLength);
$pureData = StringHelper::byteSubstr($data, $hashLength, null);
$calculatedHash = hash_hmac($this->macHash, $pureData, $key, $rawHash);
if ($this->compareString($hash, $calculatedHash)) {
return $pureData;
}
}
return false;
}
針對雜湊驗證密碼。
另請參閱 generatePasswordHash()。
public boolean validatePassword ( $password, $hash ) | ||
$password | 字串 |
要驗證的密碼。 |
$hash | 字串 |
用於驗證密碼的雜湊值。 |
return | boolean |
密碼是否正確。 |
---|---|---|
throws | yii\base\InvalidArgumentException |
在錯誤的密碼/雜湊參數上,或者如果使用 Blowfish 雜湊的 crypt() 不可用。 |
public function validatePassword($password, $hash)
{
if (!is_string($password) || $password === '') {
throw new InvalidArgumentException('Password must be a string and cannot be empty.');
}
if (
!preg_match('/^\$2[axy]\$(\d\d)\$[\.\/0-9A-Za-z]{22}/', $hash, $matches)
|| $matches[1] < 4
|| $matches[1] > 30
) {
throw new InvalidArgumentException('Hash is invalid.');
}
if (function_exists('password_verify')) {
return password_verify($password, $hash);
}
$test = crypt($password, $hash);
$n = strlen($test);
if ($n !== 60) {
return false;
}
return $this->compareString($test, $hash);
}
註冊 或 登入 以發表評論。