218

重複の可能性:
PHP双方向暗号化:取得可能なパスワードを保存する必要があります

ユーザーの外国のアカウント情報、別名rapidshareのユーザー名とパスワードなどを自分のWebサイトに保存する予定です。情報を安全に保ちたいのですが、ユーザーの情報をハッシュすると、後で使用するために取得できないことを知っています。 。

Base64は復号化可能であるため、それを単純に使用しても意味がありません。私の考えは、ユーザーをスクランブルし、復号化した後でもそのようにbase64される前後にパスすることです。復号化しようとすると、見栄えの悪いテキストが表示されます。文字列の一意のスクランブルを作成し、後で値が再入力されたときにスクランブルを解除する値を受け入れるphp関数はありますか?

助言がありますか?

4

8 に答える 8

303

パスワードを暗号化するのではなく、bcryptなどのアルゴリズムを使用してパスワードをハッシュする必要があります。この回答は、PHPでパスワードハッシュを適切に実装する方法を説明していますそれでも、暗号化/復号化する方法は次のとおりです。

$key = 'password to (en/de)crypt';
$string = ' string to be encrypted '; // note the spaces

暗号化するには:

$iv = mcrypt_create_iv(
    mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC),
    MCRYPT_DEV_URANDOM
);

$encrypted = base64_encode(
    $iv .
    mcrypt_encrypt(
        MCRYPT_RIJNDAEL_128,
        hash('sha256', $key, true),
        $string,
        MCRYPT_MODE_CBC,
        $iv
    )
);

復号化するには:

$data = base64_decode($encrypted);
$iv = substr($data, 0, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));

$decrypted = rtrim(
    mcrypt_decrypt(
        MCRYPT_RIJNDAEL_128,
        hash('sha256', $key, true),
        substr($data, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)),
        MCRYPT_MODE_CBC,
        $iv
    ),
    "\0"
);

警告:上記の例は情報を暗号化しますが、改ざんを防ぐために暗号文を認証しません。特に、提供されているコードはパディングoracle攻撃に対して脆弱であるため、セキュリティのために認証されていない暗号化に依存しないでください

参照:

また、暗号化キーに「パスワード」を使用するだけではいけません。暗号化キーはランダムな文字列です。


3v4l.orgでのデモ

echo 'Encrypted:' . "\n";
var_dump($encrypted); // "m1DSXVlAKJnLm7k3WrVd51omGL/05JJrPluBonO9W+9ohkNuw8rWdJW6NeLNc688="

echo "\n";

echo 'Decrypted:' . "\n";
var_dump($decrypted); // " string to be encrypted "
于 2009-08-17T16:49:56.117 に答える
36

セキュリティ警告:このクラスは安全ではありません。これは、意味的に安全ではないRijndael256-ECBを使用しています。「動作する」からといって「安全」という意味ではありません。また、適切なパディングを使用していないため、後でテーリングスペースが削除されます。

最近このクラスを見つけました、それは夢のように機能します!

class Encryption {
    var $skey = "yourSecretKey"; // you can change it

    public  function safe_b64encode($string) {
        $data = base64_encode($string);
        $data = str_replace(array('+','/','='),array('-','_',''),$data);
        return $data;
    }

    public function safe_b64decode($string) {
        $data = str_replace(array('-','_'),array('+','/'),$string);
        $mod4 = strlen($data) % 4;
        if ($mod4) {
            $data .= substr('====', $mod4);
        }
        return base64_decode($data);
    }

    public  function encode($value){ 
        if(!$value){return false;}
        $text = $value;
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->skey, $text, MCRYPT_MODE_ECB, $iv);
        return trim($this->safe_b64encode($crypttext)); 
    }

    public function decode($value){
        if(!$value){return false;}
        $crypttext = $this->safe_b64decode($value); 
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->skey, $crypttext, MCRYPT_MODE_ECB, $iv);
        return trim($decrypttext);
    }
}

そしてそれを呼ぶために:

$str = "My secret String";

$converter = new Encryption;
$encoded = $converter->encode($str );
$decoded = $converter->decode($encoded);    

echo "$encoded<p>$decoded";
于 2011-02-02T14:48:00.383 に答える
18

セキュリティ警告:このコードは安全ではありません。

実例

define('SALT', 'whateveryouwant'); 

function encrypt($text) 
{ 
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SALT, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)))); 
} 

function decrypt($text) 
{ 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, SALT, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))); 
} 

$encryptedmessage = encrypt("your message"); 
echo decrypt($encryptedmessage); 
于 2010-11-22T10:51:10.857 に答える
12

暗号化を扱うときによく知っておくべきことの1つは次のとおりです。

賢くなり、自分のものを発明しようとすると、通常、何か不安が残ります。

PHPに付属している暗号化拡張機能の1つを使用するのがおそらく最善でしょう。

于 2009-08-17T16:50:07.817 に答える
3

セキュリティ警告:このコードは安全ではありません。選択暗号文攻撃に対して脆弱であることに加えて、その依存unserialize()性により、PHPオブジェクトインジェクションに対して脆弱になります。

文字列/配列を処理するには、次の2つの関数を使用します。

function encryptStringArray ($stringArray, $key = "Your secret salt thingie") {
 $s = strtr(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), serialize($stringArray), MCRYPT_MODE_CBC, md5(md5($key)))), '+/=', '-_,');
 return $s;
}

function decryptStringArray ($stringArray, $key = "Your secret salt thingie") {
 $s = unserialize(rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode(strtr($stringArray, '-_,', '+/=')), MCRYPT_MODE_CBC, md5(md5($key))), "\0"));
 return $s;
}

文字列/配列は暗号化の前にシリアル化されるため、URLを介して文字列または配列を保存/送信できるように柔軟性があります。

于 2010-10-04T12:08:58.830 に答える
2

これはあなたにわずかな保護を与えるだけです。攻撃者がアプリケーションで任意のコードを実行できる場合、アプリケーションとまったく同じ方法でパスワードを取得できます。秘密鍵をファイルに保存し、それを使用してデータベースへの途中で暗号化し、途中で復号化すると、SQLインジェクション攻撃や誤って配置されたデータベースバックアップからある程度保護される可能性があります。ただし、SQLインジェクションの問題を完全に回避するには、bindparamsを使用する必要があります。

暗号化することにした場合は、これに高レベルの暗号ライブラリを使用する必要がありますそうしないと、間違ってしまいます。キーの設定、メッセージのパディング、整合性チェックを正しく行う必要があります。そうしないと、暗号化の作業はほとんど役に立ちません。一例として、GPGMEが適しています。Mcryptのレベルが低すぎるため、おそらく間違っているでしょう。

于 2009-08-17T16:53:45.970 に答える
1

mycrypt()をチェックしてください:http://us.php.net/manual/en/book.mcrypt.php

また、postgresを使用している場合は、データベースレベルの暗号化にpgcryptoがあります。(検索と並べ替えが簡単になります)

于 2009-08-17T16:50:59.890 に答える
0

コードにアクセスできる場合でも、データベース内のデータを暗号化/復号化するための最良のアイデアは、user-passユーザーごとにプライベートパスワード()とすべてのユーザーにプライベートコード()の2つの異なるパスを使用することsystem-passです。

シナリオ

  1. user-passmd5とともにデータベースに保存され、各ユーザーがシステムにログインすることを検証するために使用されます。このユーザーパスはユーザーごとに異なります。
  2. データベースの各ユーザーエントリには、md5system-passにデータの暗号化/復号化用のaがあります。このシステムパスは、各ユーザーで同じです。
  3. ユーザーがシステムから削除されるときはいつでも、セキュリティの問題を回避するために、古いシステムパスで暗号化されたすべてのデータを新しいシステムパスで再度暗号化する必要があります。
于 2012-11-18T15:19:24.967 に答える