24

ファイルを暗号化または復号化するいくつかの関数を作成しようとしており、ここにあるクラスを使用してこれを達成しようとしています:

http://www.itnewb.com/v/PHP-Encryption-Decryption-Using-the-MCrypt-Library-libmcrypt

以下の暗号化機能は、ファイルを暗号化し、目的のディレクトリに配置するように見えるという点で、機能しているようです。私は今ファイルを復号化しようとしていますが、「復号化を完了できませんでした」というメッセージが表示されて死ぬだけです(そこにコード化されています...)phpエラーログには何もないので、なぜ失敗したのかわかりません、しかし mcrypt は私にとってまったく新しいものなので、ここで何か間違ったことをしていると信じがちです...

関数は次のとおりです。

//ENCRYPT FILE
    function encryptFile() {
        global $cryptastic;
        $pass = PGPPASS;
        $salt = PGPSALT;
        $key = $cryptastic->pbkdf2($pass, $salt, 1000, 32) or die("Failed to generate secret key.");

        if ($handle = opendir(PATH.'/ftpd')) {
            while (false !== ($file = readdir($handle))) {
                if ($file != "." && $file != "..") {
                    $newfile = PATH.'/encrypted/'.$file.'.txt';
                    $msg = file_get_contents(PATH.'/ftpd/'.$file);
                    $encrypted = $cryptastic->encrypt($msg, $key) or die("Failed to complete encryption.");
                    $nfile = fopen($newfile, 'w');
                    fwrite($nfile, $encrypted);
                    fclose($nfile);
                    unlink(PATH.'/ftpd/'.$file);

                }
            }
            closedir($handle);
        }       


//DECRYPT FILE
    function inFTP() {
        global $cryptastic;
        $pass = PGPPASS;
        $salt = PGPSALT;
        $key = $cryptastic->pbkdf2($pass, $salt, 1000, 32) or die("Failed to generate secret key.");

        if ($handle = opendir(PATH.'/encrypted')) {
            while (false !== ($file = readdir($handle))) {
                if ($file != "." && $file != "..") {
                    $newfile = PATH.'/decrypted/'.$file;
                    $msg = PATH.'/encrypted/'.$file;
                    $decrypted = $cryptastic->decrypt($msg, $key) or die("Failed to complete decryption.");
                    $nfile = fopen($newfile, 'w');
                    fwrite($nfile, $decrypted);
                    fclose($nfile);
                    //unlink(PATH.'/encrypted/'.$file);

                }
            }
            closedir($handle);
        }       
        //$crypt->decrypt($file);
    }
4

4 に答える 4

57

mcrypt は放棄されたソフトウェアであり、使用が推奨されなくなったため、openssl を使用した例を次に示します。

class AES256Encryption
{
    public const BLOCK_SIZE = 8;
    public const IV_LENGTH = 16;
    public const CIPHER = 'AES256';

    public static function generateIv(bool $allowLessSecure = false): string
    {
        $success = false;
        $random = openssl_random_pseudo_bytes(openssl_cipher_iv_length(static::CIPHER));
        if (!$success) {
            if (function_exists('sodium_randombytes_random16')) {
                $random = sodium_randombytes_random16();
            } else {
                try {
                    $random = random_bytes(static::IV_LENGTH);
                }
                catch (Exception $e) {
                    if ($allowLessSecure) {
                        $permitted_chars = implode(
                            '',
                            array_merge(
                                range('A', 'z'),
                                range(0, 9),
                                str_split('~!@#$%&*()-=+{};:"<>,.?/\'')
                            )
                        );
                        $random = '';
                        for ($i = 0; $i < static::IV_LENGTH; $i++) {
                            $random .= $permitted_chars[mt_rand(0, (static::IV_LENGTH) - 1)];
                        }
                    }
                    else {
                        throw new RuntimeException('Unable to generate initialization vector (IV)');
                    }
                }
            }
        }
        return $random;
    }

    protected static function getPaddedText(string $plainText): string
    {
        $stringLength = strlen($plainText);
        if ($stringLength % static::BLOCK_SIZE) {
            $plainText = str_pad($plainText, $stringLength + static::BLOCK_SIZE - $stringLength % static::BLOCK_SIZE, "\0");
        }
        return $plainText;
    }

    public static function encrypt(string $plainText, string $key, string $iv): string
    {
        $plainText = static::getPaddedText($plainText);
        return base64_encode(openssl_encrypt($plainText, static::CIPHER, $key, OPENSSL_RAW_DATA, $iv));
    }

    public static function decrypt(string $encryptedText, string $key, string $iv): string
    {
        return openssl_decrypt(base64_decode($encryptedText), static::CIPHER, $key, OPENSSL_RAW_DATA, $iv);
    }
}

$text = '8SViI0Gz4r-p7A15YxkwjOBFuW*@NTtbm{U]D&E=~6yLM+adX'P;h3$,KJ%/eo>}<Rs:2#gZ.9fqn"Cv_^[(H\c!)?`Ql';
$key = 'secretkey';
$iv = AES256Encryption::generateIv();
$encryptedText = AES256Encryption::encrypt($text, $key, $iv);
$decryptedText = AES256Encryption::decrypt($encryptedText, $key, $iv);

printf('Original Text: %s%s', $text, PHP_EOL);
printf('Encrypted: %s%s', $encryptedText, PHP_EOL);
printf('Decrypted: %s%s', $decryptedText, PHP_EOL);

出力:

// Long string with lots of different characters
Original Text: 8SViI0Gz4r-p7A15YxkwjOBFuW*@NTtbm{U]D&E=~6yLM+adX'P;h3$,KJ%/eo>}<Rs:2#gZ.9fqn"Cv_^[(H\c!)?`Ql
Encrypted    : rsiF4PMCMyvAp+CTuJrxJYGoV4BSy8Fy+q+FL8m64+Mt5V3o0HS0elRkWXsy+//hPjzNhjmVktxVvMY55Negt4DyLcf2QpH05wUX+adJDe634J/9fWd+nlEFoDutXuhY+/Kep9zUZFDmLmszJaBHWQ==
Decrypted    : 8SViI0Gz4r-p7A15YxkwjOBFuW*@NTtbm{U]D&E=~6yLM+adX'P;h3$,KJ%/eo>}<Rs:2#gZ.9fqn"Cv_^[(H\c!)?`Ql 

古い回答

mcrypt を使用した暗号化には、この PHP5 クラスを試してください。この場合、AES 暗号化を使用しています。使用するサイトごとにキーを変更する必要があります。少なくともそれを使用しない場合は、独自のバージョンを作成する際に役立つ場合があります。

<?php

class Encryption
{
    const CIPHER = MCRYPT_RIJNDAEL_128; // Rijndael-128 is AES
    const MODE   = MCRYPT_MODE_CBC;

    /* Cryptographic key of length 16, 24 or 32. NOT a password! */
    private $key;
    public function __construct($key) {
        $this->key = $key;
    }

    public function encrypt($plaintext) {
        $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE);
        $iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM);
        $ciphertext = mcrypt_encrypt(self::CIPHER, $this->key, $plaintext, self::MODE, $iv);
        return base64_encode($iv.$ciphertext);
    }

    public function decrypt($ciphertext) {
        $ciphertext = base64_decode($ciphertext);
        $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE);
        if (strlen($ciphertext) < $ivSize) {
            throw new Exception('Missing initialization vector');
        }

        $iv = substr($ciphertext, 0, $ivSize);
        $ciphertext = substr($ciphertext, $ivSize);
        $plaintext = mcrypt_decrypt(self::CIPHER, $this->key, $ciphertext, self::MODE, $iv);
        return rtrim($plaintext, "\0");
    }
}

使用法:

$key = /* CRYPTOGRAPHIC!!! key */;
$crypt = new Encryption($key);
$encrypted_string = $crypt->encrypt('this is a test');
$decrypted_string = $crypt->decrypt($encrypted_string); // this is a test

ノート:

  • このクラスは、バイナリ データ (NUL バイトで終了する可能性があります) で使用するのは安全ではありません。
  • このクラスは、認証された暗号化を提供しません。
于 2010-03-15T15:49:06.663 に答える
2

ジョンの答えは良いですが、バイナリの安全性の問題を修正するためだけに base64 エンコーディングを使用するのはやり過ぎで、暗号化されたファイルは元のファイルより 33% 大きくなります。上記の問題をすべて透過的に解決する AES Crypt ファイル形式の PHP 実装を次に示します。

https://github.com/philios33/PHP-AES-ファイル暗号化

バイナリセーフであり、認証された暗号化が含まれています。オープン ソースの aes crypt ファイル形式 (.aes) を使用しているため、他の .aes ソフトウェアと完全に互換性があります。

https://www.aescrypt.com/

暗号化または復号化に関係なく、インターフェイスは非常にシンプルです。ソースファイルとパスワードを与えるだけです。

于 2014-12-05T00:53:41.607 に答える
2

データの暗号化/復号化に Mcrypt を使用しないでください。あなたの質問と受け入れられた回答に示されているように、データは認証されていません。つまり、選択された暗号文攻撃の犠牲になります。

さらに、開発者が暗号化プリミティブを正しく組み合わせられるように、多大な努力が払われてきました。そのため、PHP プロジェクトには Mcrypt の代わりに libsodium を使用する必要があります。libsodium は NaCl のフォークです。NaCl/libsodium は、MAC タグの検証によるタイミング攻撃など、開発者が陥る多くの暗号化の落とし穴を取り除くために作成されています。

Mcrypt は PHP 7.1 で廃止され、libsodim は PHP で暗号化を処理するための推奨される方法です。

PHP プロジェクトで libsodium を使用するのは簡単で安全です。Scott Arciszewski は、https: //paragonie.com/book/pecl-libsodium で PHP での libsodium の使用に関する詳細な電子ブックを書きました。PHP 暗号化を行っている人は、一読の価値があります。

于 2016-12-09T18:00:00.030 に答える
1

CakePHPには、 rijndaelのかなり優れた実装があります。法的な影響がわからないため、ここにコードを直接投稿することはしません。

Security::rijndael()メソッドの API ドキュメントは次のとおりです。

ファイルをエンコードする場合は、base64_encode()このメソッドを呼び出す前に ' encrypt' を指定し、base64_decode()このメソッドを呼び出した後に' decrypt'を指定する必要があります。

于 2013-09-20T20:53:50.133 に答える