> YII 类库手册 > CSecurityManager
system.base
继承 class CSecurityManager » CApplicationComponent » CComponent
实现 IApplicationComponent
源自 1.0
版本 $Id: CSecurityManager.php 3555 2012-02-09 10:29:44Z mDOMba $
源码
CSecurityManager提供了私有密钥,哈希和加密功能。

使用CSecurityManager为Yii组件和应用程序提供安全相关功能。 例如,它应用在cookie验证功能 以防止cookie数据被伪造。

CSecurityManager主要是用来保护数据不被篡改和查看。 它可以生成HMAC和加密数据。 通过设置ValidationKey来设置私钥来生成HMAC。 用来加密数据的密钥是由EncryptionKey指定。 如果上面的密钥没有明确设定,那么会生成和使用随机密钥。

为了能使用HMAC来保护数据,请调用hashData();然后检查数据是否被篡改, 如果数据没有被篡改,那么调用validateData()时会返回真实的数据。 用来生成HMAC的算法是由 validation指定的。

分别调用encrypt()和decrypt()来加密和解密, 这个过程会使用3DES加密算法。 注意,一定要安装和加载PHP Mcrypt。

CSecurityManager是一个内核级应用组件, 可以通过CApplication::getSecurityManager()进行访问。

公共属性

属性 类型 描述 定义在
behaviors array 这个应用组件附加的行为。 这此行为将在应用组件调用init时附加在应用组件上。 请参照CModel::behaviors如何指定此属性值。 CApplicationComponent
cryptAlgorithm mixed 用于encrypt和decrypt的加密算法名字。 这个会作为第一个参数传递给{@link Http://php. CSecurityManager
encryptionKey string 用来加密/解密数据的私钥。 如果没有明确指定密钥,那么会生成和使用随机密钥。 CSecurityManager
hashAlgorithm string 用于computeHMAC的哈希算法名字。 参见{@link http://php. CSecurityManager
isInitialized boolean 检查应用组件是否已经初始化。 CApplicationComponent
validation string 这个方法自版本1.1.3被弃用。 CSecurityManager
validationKey string 用来生成HMAC的私钥。 如果没有明确指定密钥,那么会生成和使用随机密钥。 CSecurityManager

公共方法

方法 描述 定义在
__call() 如果类中没有调的方法名,则调用这个方法。 CComponent
__get() 返回一个属性值、一个事件处理程序列表或一个行为名称。 CComponent
__isset() 检查一个属性是否为null。 CComponent
__set() 设置一个组件的属性值。 CComponent
__unset() 设置一个组件的属性为null。 CComponent
asa() 返回这个名字的行为对象。 CComponent
attachBehavior() 附加一个行为到组件。 CComponent
attachBehaviors() 附加一个行为列表到组件。 CComponent
attachEventHandler() 为事件附加一个事件处理程序。 CComponent
canGetProperty() 确定属性是否可读。 CComponent
canSetProperty() 确定属性是否可写。 CComponent
decrypt() 解密数据 CSecurityManager
detachBehavior() 从组件中分离一个行为。 CComponent
detachBehaviors() 从组件中分离所有行为。 CComponent
detachEventHandler() 分离一个存在的事件处理程序。 CComponent
disableBehavior() 禁用一个附加行为。 CComponent
disableBehaviors() 禁用组件附加的所有行为。 CComponent
enableBehavior() 启用一个附加行为。 CComponent
enableBehaviors() 启用组件附加的所有行为。 CComponent
encrypt() 加密数据。 CSecurityManager
evaLuateExpression() 计算一个PHP表达式,或根据组件上下文执行回调。 CComponent
getEncryptionKey() 返回用来加密/解密数据的私钥。 如果没有明确指定密钥,那么会生成和使用随机密钥。 CSecurityManager
getEventHandlers() 返回一个事件的附加处理程序列表。 CComponent
getIsInitialized() 检查应用组件是否已经初始化。 CApplicationComponent
getValidation() 这个方法自版本1.1.3被弃用。 CSecurityManager
getValidationKey() 返回用来生成HMAC的私钥。 如果没有明确指定密钥,那么会生成和使用随机密钥。 CSecurityManager
hasEvent() 确定一个事件是否定义。 CComponent
hasEventHandler() 检查事件是否有附加的处理程序。 CComponent
hasProperty() 确定属性是否被定义。 CComponent
hashData() 将HMAC作为数据的前缀。 CSecurityManager
init() CSecurityManager
raiseEvent() 发起一个事件。 CComponent
setEncryptionKey() 设置用于加密/解密数据的密钥。 CSecurityManager
setValidation() 这个方法自版本1.1.3被弃用。 CSecurityManager
setValidationKey() 设置用来产生HMAC的密钥 CSecurityManager
validateData() 验证数据是否被篡改过。 CSecurityManager

受保护方法

方法 描述 定义在
computeHMAC() 计算ValidationKey数据的HMAC。 CSecurityManager
generateRandomKey() CSecurityManager
openCryptModule() 根据指定配置打开cryptAlgorithm指定的配置mcrypt的模块。 CSecurityManager

属性详细

cryptAlgorithm 属性 (可用自 v1.1.3)
public mixed $cryptAlgorithm;

用于encrypt和decrypt的加密算法名字。 这个会作为第一个参数传递给mcrypt_module_open。

这个属性也可以配置为数组。这种情况下,数组元素会作为参数按顺序传递给mcrypt_module_open。 例如,array('rijndael-256', '', 'ofb', '')

默认是‘des’,意味着使用DES加密算法。

encryptionKey 属性
public string getEncryptionKey()
public void setEncryptionKey(string $value)

用来加密/解密数据的私钥。 如果没有明确指定密钥,那么会生成和使用随机密钥。

hashAlgorithm 属性 (可用自 v1.1.3)
public string $hashAlgorithm;

用于computeHMAC的哈希算法名字。 参见hash-algos查看可使用的哈希算法。 注意,如果你使用PHP 5.1.1或更低版本,只能使用‘sha1’或者‘md5’。

默认是‘sha1’,意味着使用SHA1哈希算法。

validation 属性
public string getValidation()
public void setValidation(string $value)

这个方法自版本1.1.3被弃用。 请另用hashAlgorithm代替。

validationKey 属性
public string getValidationKey()
public void setValidationKey(string $value)

用来生成HMAC的私钥。 如果没有明确指定密钥,那么会生成和使用随机密钥。

方法详细

computeHMAC() 方法
protected string computeHMAC(string $data, string $key=NULL)
$data string 用来生成HMAC的数据
$key string 用来生成HMAC的私钥。默认为null,意味着使用validationKey。
{return} string 数据的HMAC
protected function computeHMAC($data,$key=null)
{
    if(
$key===null)
        
$key=$this->getValidationKey();

    if(
function_exists('hash_hmac'))
        return 
hash_hmac($this->hashAlgorithm$data$key);

    if(!
strcasecmp($this->hashAlgorithm,'sha1'))
    {
        
$pack='H40';
        
$func='sha1';
    }
    else
    {
        
$pack='H32';
        
$func='md5';
    }
    if(
$this->strlen($key) > 64)
        
$key=pack($pack$func($key));
    if(
$this->strlen($key) < 64)
        
$key=str_pad($key64chr(0));
    
$key=$this->substr($key,0,64);
    return 
$func((str_repeat(chr(0x5C), 64) ^ $key) . pack($pack$func((str_repeat(chr(0x36), 64) ^ $key) . $data)));
}

计算ValidationKey数据的HMAC。

decrypt() 方法
public string decrypt(string $data, string $key=NULL)
$data string 要解密的数据。
$key string 解密密钥。默认为null,意味着使用EncryptionKey。
{return} string 解密的数据
public function decrypt($data,$key=null)
{
    
$module=$this->openCryptModule();
    
$key=$this->substr($key===null md5($this->getEncryptionKey()) : $key,0,mcrypt_enc_get_key_size($module));
    
$ivSize=mcrypt_enc_get_iv_size($module);
    
$iv=$this->substr($data,0,$ivSize);
    
mcrypt_generic_init($module,$key,$iv);
    
$decrypted=mdecrypt_generic($module,$this->substr($data,$ivSize,$this->strlen($data)));
    
mcrypt_generic_deinit($module);
    
mcrypt_module_close($module);
    return 
rtrim($decrypted,"\0");
}

解密数据

encrypt() 方法
public string encrypt(string $data, string $key=NULL)
$data string 要加密的数据。
$key string 加密密钥。默认为null,意味着使用EncryptionKey。
{return} string 加密的数据
public function encrypt($data,$key=null)
{
    
$module=$this->openCryptModule();
    
$key=$this->substr($key===null md5($this->getEncryptionKey()) : $key,0,mcrypt_enc_get_key_size($module));
    
srand();
    
$iv=mcrypt_create_iv(mcrypt_enc_get_iv_size($module), MCRYPT_RAND);
    
mcrypt_generic_init($module,$key,$iv);
    
$encrypted=$iv.mcrypt_generic($module,$data);
    
mcrypt_generic_deinit($module);
    
mcrypt_module_close($module);
    return 
$encrypted;
}

加密数据。

generateRandomKey() 方法
protected string generateRandomKey()
{return} string 随机生成的私钥
protected function generateRandomKey()
{
    return 
sprintf('%08x%08x%08x%08x',mt_rand(),mt_rand(),mt_rand(),mt_rand());
}

getEncryptionKey() 方法
public string getEncryptionKey()
{return} string 用来加密/解密数据的私钥。 如果没有明确指定密钥,那么会生成和使用随机密钥。
public function getEncryptionKey()
{
    if(
$this->_encryptionKey!==null)
        return 
$this->_encryptionKey;
    else
    {
        if((
$key=Yii::app()->getGlobalState(self::STATE_ENCRYPTION_KEY))!==null)
            
$this->setEncryptionKey($key);
        else
        {
            
$key=$this->generateRandomKey();
            
$this->setEncryptionKey($key);
            
Yii::app()->setGlobalState(self::STATE_ENCRYPTION_KEY,$key);
        }
        return 
$this->_encryptionKey;
    }
}

getValidation() 方法
public string getValidation()
{return} string
public function getValidation()
{
    return 
$this->hashAlgorithm;
}

这个方法自版本1.1.3被弃用。 请另用hashAlgorithm代替。

getValidationKey() 方法
public string getValidationKey()
{return} string 用来生成HMAC的私钥。 如果没有明确指定密钥,那么会生成和使用随机密钥。
public function getValidationKey()
{
    if(
$this->_validationKey!==null)
        return 
$this->_validationKey;
    else
    {
        if((
$key=Yii::app()->getGlobalState(self::STATE_VALIDATION_KEY))!==null)
            
$this->setValidationKey($key);
        else
        {
            
$key=$this->generateRandomKey();
            
$this->setValidationKey($key);
            
Yii::app()->setGlobalState(self::STATE_VALIDATION_KEY,$key);
        }
        return 
$this->_validationKey;
    }
}

hashData() 方法
public string hashData(string $data, string $key=NULL)
$data string 要哈希的数据。
$key string 用来生成HMAC的私钥。默认为 null,意味着使用validationKey。
{return} string 以HMAC为前缀的数据
public function hashData($data,$key=null)
{
    return 
$this->computeHMAC($data,$key).$data;
}

将HMAC作为数据的前缀。

init() 方法
public void init()
public function init()
{
    
parent::init();
    
$this->_mbstring=extension_loaded('mbstring');
}

openCryptModule() 方法 (可用自 v1.1.3)
protected resource openCryptModule()
{return} resource mycrypt 模块处理。
protected function openCryptModule()
{
    if(
extension_loaded('mcrypt'))
    {
        if(
is_array($this->cryptAlgorithm))
            
$module=@call_user_func_array('mcrypt_module_open',$this->cryptAlgorithm);
        else
            
$module=@mcrypt_module_open($this->cryptAlgorithm,''MCRYPT_MODE_CBC,'');

        if(
$module===false)
            throw new 
CException(Yii::t('yii','Failed to initialize the mcrypt module.'));

        return 
$module;
    }
    else
        throw new 
CException(Yii::t('yii','CSecurityManager requires PHP mcrypt extension to be loaded in order to use data encryption feature.'));
}

根据指定配置打开cryptAlgorithm指定的配置mcrypt的模块。

setEncryptionKey() 方法
public void setEncryptionKey(string $value)
$value string 用于加密/解密数据的密钥。
public function setEncryptionKey($value)
{
    if(!empty(
$value))
        
$this->_encryptionKey=$value;
    else
        throw new 
CException(Yii::t('yii','CSecurityManager.encryptionKey cannot be empty.'));
}

setValidation() 方法
public void setValidation(string $value)
$value string -
public function setValidation($value)
{
    
$this->hashAlgorithm=$value;
}

这个方法自版本1.1.3被弃用。 请另用hashAlgorithm代替。

setValidationKey() 方法
public void setValidationKey(string $value)
$value string 用来产生HMAC的密钥
public function setValidationKey($value)
{
    if(!empty(
$value))
        
$this->_validationKey=$value;
    else
        throw new 
CException(Yii::t('yii','CSecurityManager.validationKey cannot be empty.'));
}

validateData() 方法
public string validateData(string $data, string $key=NULL)
$data string 要验证的数据。 数据一定是事前使用hashData()来生成的。
$key string 用来生成HMAC的私钥。默认为null,意味着使用validationKey。
{return} string 与HMAC剥离的真实数据。 如果数据被篡改过,则返回 false。
public function validateData($data,$key=null)
{
    
$len=$this->strlen($this->computeHMAC('test'));
    if(
$this->strlen($data)>=$len)
    {
        
$hmac=$this->substr($data,0,$len);
        
$data2=$this->substr($data,$len,$this->strlen($data));
        return 
$hmac===$this->computeHMAC($data2,$key)?$data2:false;
    }
    else
        return 
false;
}

验证数据是否被篡改过。

上一篇:
下一篇: