0

友人と協力してWebサイトで署名されたCookieを取得していますが、mcryptとMCRYPT_RIJNDAEL_256で暗号化しようとすると多くの問題が発生します。私はCookieが正常に機能しているので、問題はCookieの値を暗号化/復号化する場合にのみ発生します。

Cookieを復号化しようとすると、次のエラーが表示されます。

Notice: unserialize(): Error at offset 0 of 93 bytes in /var/samba/www/xxx/src/data/include/yyy/Cookie.php on line 94

この正確な行は、次のものに対応します。

$this->_cookie["value"] =  unserialize(mdecrypt_generic($tv, $cookie_value));

そして、これが私が暗号化/復号化する方法です。

まず、Cookieを送信します。

    $tv = mcrypt_module_open(MCRYPT_RIJNDAEL_256, null, "ctr", null);
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($tv), MCRYPT_RAND);
    mcrypt_generic_init($tv, "t3stp4ssw0rd", $iv);

    $this->_cookie["value"] =  base64_encode(mcrypt_generic($tv, serialize($this->_cookie["value"])));

    mcrypt_generic_deinit($tv);
    mcrypt_module_close($tv);

    setrawcookie($this->_cookie["name"],
                 $this->_cookie["value"],
                 $this->_cookie["expire"],
                 $this->_cookie["path"],
                 $this->_cookie["domain"],
                 $this->_cookie["secure"],
                 $this->_cookie["httponly"]);

PD:うん、素敵なテストパスワード;-)

cookieのfirebugに表示される値は次のとおりです。

oKWdbVLX9T+mbOut4swo/aXr0g5O/3ApqfWZ1GZlrwwMSTa+M4n8Uey0UQs827HB7tilc/OzUPWQxoNvnAIkP5CFGkvgn+j+I36qN6dB0HmOUPlkNXJlz8Tfqxrjf8Gx

値を復号化する必要があるgetcookieは次のとおりです。

    $this->_cookie["name"] = $cookie_name;
    $this->_cookie["value"] = $_COOKIE[$cookie_name];

    $cookie_value = base64_decode($this->_cookie["value"]);

    $tv = mcrypt_module_open(MCRYPT_RIJNDAEL_256, null, "ctr", null);
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($tv), MCRYPT_RAND);
    mcrypt_generic_init($tv, "t3stp4ssw0rd", $iv);

    $this->_cookie["value"] =  unserialize(mdecrypt_generic($tv, $cookie_value));

    mcrypt_generic_deinit($tv);
    mcrypt_module_close($tv);

    return $_COOKIE[$cookie_name];

問題は、復号化されたデータの値を逆シリアル化しようとしたときです。どこが問題になるか知っている人はいますか?

前もって感謝します!

アップデート:

    $cookie_value = base64_decode($this->_cookie["value"]);

    $td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, "", "cfb", "");
    $ks = mcrypt_enc_get_key_size($td);
    $key = substr(sha1("t3stp4ssw0rd"), 0, $ks);

    $ivs = mcrypt_enc_get_iv_size($td);
    $iv = substr($cookie_value, 0, $ivs);

    $cookie_value = substr($cookie_value, $ivs);

    mcrypt_generic_init($td, $key, $iv);

    $cookie_value = mdecrypt_generic($td, $cookie_value);

    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);

    $this->_cookie["value"] =  unserialize($cookie_value);

エラーを返しますWarning: mcrypt_generic_init(): Iv size incorrect; supplied length: 0, needed: 32

4

2 に答える 2

2

このオフセットエラーは通常、値の1つの長さが、シリアル化されたデータによって示される指定された長さに対応していないことを意味します。私の経験では、これは通常次のようになります。

  • 前のポスターが言ったように、文字をエスケープするためにバックスラッシュが挿入されています
  • エンコーディングの問題。これは通常、一部の文字がシリアル化されたときに1バイトであると計算されたが、シリアル化を解除したときに突然2バイトになる場合に発生します。これは、たとえばISO-8859-1文字セットがある場合に発生する可能性がありますが、操作によってはUTF-8に変更されます。

推測すると、2番目のポイントはおそらくあなたの問題がどこにあるかということです。最初の手順はserialize->encrypt->base64_encodeで、次に順序を逆にしますが、どこかで文字エンコードが混乱しているのではないかと思います。

編集済み: わかりました。コードを確認しましたが、暗号化/復号化に問題があります。復号化によって、復号化された値が返されません。少し前に、私がMcryptに使用しているこの関数に出くわしました(どこにあるかを思い出して、正しく属性を付けることができるようにしたいと思います)。エンコードとデコードの両方で機能します。それを試して、問題が解決するかどうかを確認してください(それが行わないのはbase64_encodeだけです)。あなたの問題はあなたがいくつかの必要なステップを逃したことだったと思います。

function encDec( $data, $key, $encrypt=true, $cypher='rijndael-128') {

    if (function_exists('mcrypt_module_open')) {

        # Serialize, if encrypting
        if ( $encrypt ) { $data = serialize($data); } 

        # Open cipher module
        if ( ! $td = mcrypt_module_open($cypher, '', 'cfb', '') )
            return false;

        $ks = mcrypt_enc_get_key_size($td);     # Required key size
        $key = substr(sha1($key), 0, $ks);      # Harden / adjust length

        $ivs = mcrypt_enc_get_iv_size($td);     # IV size

        $iv = $encrypt ?
            mcrypt_create_iv($ivs, MCRYPT_RAND) :   # Create IV, if encrypting
            substr($data, 0, $ivs);                 # Extract IV, if decrypting

        # Extract data, if decrypting
        if ( ! $encrypt ) $data = substr($data, $ivs);

        if ( mcrypt_generic_init($td, $key, $iv) !== 0 ) # Initialize buffers
            return false;

        $data = $encrypt ?
            mcrypt_generic($td, $data) :    # Perform encryption
            mdecrypt_generic($td, $data);   # Perform decryption

        if ( $encrypt ) $data = $iv . $data;    # Prepend IV, if encrypting

        mcrypt_generic_deinit($td);             # Clear buffers
        mcrypt_module_close($td);               # Close cipher module

        # Unserialize, if decrypting
        if ( ! $encrypt ) $data = unserialize($data);

    }

    return $data;
}
于 2011-03-25T10:11:48.307 に答える
0

"Cookie情報の引用符がバックスラッシュを使用してエスケープされていないことを確認してください。引用符がエスケープされている場合は、暗号化する前に削除してください。このスレッドを参照してください->オフセットでのPHPのシリアル化解除エラー、一部のサーバーでは機能しますが、他のサーバーでは機能しません

于 2011-03-25T10:00:58.407 に答える