Yii 2替换CSecurityManager类

时间:2016-02-22 09:41:52

标签: php encryption yii yii2

我在DB中有一些数据是使用来自CSecurityManager类的Yii :: app() - > securityManager-> encrypt方法加密的。

现在我有Yii 2应用程序,Yii2中不存在此类。使用encryptByKey / decryptByKey方法有yii \ base \ Security类,但我不知道如何使用它来正确解密现有数据。

有什么建议吗?

感谢。

1 个答案:

答案 0 :(得分:2)

设计 Yii 2 时,向后兼容性是次要考虑因素。 Yii 2 是一个完全不同的代码库,从头开始重新设计。开发人员的目标是创建最好的框架,而不是保持最大的向后兼容性。在这些更改中, Yii 1 Yii 2 中的加密/解密方法不兼容。

这不是因为在{em> Yii 2.0.3 (release notes mcryptopenssl放弃mcrypt而触发的代码集大不相同,discussion 3}}),因为这种改变是向后兼容的。而 Yii 2.0.0 Yii 1.1.x 不兼容,尽管两者都使用[IV][ciphertext],因为加密方法的输出不同:

  • Yii 1 [keySalt][MAC][IV][ciphertext]
  • Yii 2 [keySalt]

其中[MAC]是随机密钥,[IV]是消息验证代码,[ciphertext]是初始化向量,use yii\helpers\StringHelper; function yii_legacy_decrypt($data,$key=null) { $module=@mcrypt_module_open('des','', MCRYPT_MODE_CBC,''); $key=StringHelper::byteSubstr($key===null ? md5(Yii::$app->security->getRandomString(32)) : $key,0,mcrypt_enc_get_key_size($module)); $ivSize=mcrypt_enc_get_iv_size($module); $iv=StringHelper::byteSubstr($data,0,$ivSize); mcrypt_generic_init($module,$key,$iv); $decrypted=mdecrypt_generic($module,StringHelper::byteSubstr($data,$ivSize,StringHelper::byteLength($data))); mcrypt_generic_deinit($module); mcrypt_module_close($module); return rtrim($decrypted,"\0"); } 是真正的加密数据本身。由于 Yii 2 中的解密算法没有为 Yii 1 生成的输入做好准备,因此它们不兼容。 Yii 2 的解决方案被认为是优越的,因为如果数据被篡改则更容易检测到。

总结如果您想要向后兼容,那么您有两个解决方案:

  1. 使用 Yii 1 Yii 2 ,如official guide中所述。
  2. 仅使用 Yii 1 中的相关解密方法。这当然需要一些更改(不仅仅是复制粘贴),因为原始代码依赖于 Yii 1 框架。
  3. 在这里,这应该有效:

    import javax.swing.*;
    
    public class Rich04
    {
    
    
    public static void main (String[] args)  
      {
    
        String[] ddList = {"Betray", "Stay silent"}; 
        Object selectedValue;  
        int code;
    
        selectedValue = JOptionPane.showInputDialog(
                    null,
                    "Choose one",  
                    "Prisoner's Dilema",                 
                          JOptionPane.QUESTION_MESSAGE,  
                          null,                 
                          ddList,                
                    ddList[1]);             
    
        for (int i=0; i<ddList.length; i++)
            if (ddList[i].equals(selectedValue))
    
                JOptionPane.showMessageDialog(
                    null,
                    "The user selected " + ddList[i],
                    "Decision",
                    JOptionPane.INFORMATION_MESSAGE);
    
     }
    
    }