サーチ…
備考
/* Base64 Encoded Encryption / $enc_data = base64_encode( openssl_encrypt($data, $method, $password, true, $iv) ); / Decode and Decrypt */ $dec_data = base64_decode( openssl_decrypt($enc_data, $method, $password, true, $iv) );
暗号化とエンコードを行うこの方法は、ベース64のエンコードを解除する前に、コードを解読するときに表示されるようには機能しません。
あなたは逆の順序でこれを行う必要があります。
/ This way instead / $enc_data=base64_encode(openssl_encrypt($data, $method, $pass, true, $iv)); $dec_data=openssl_decrypt(base64_decode($enc_data), $method, $pass, true, $iv);
対称暗号
この例は、CBCモードのAES 256対称暗号を示しています。初期化ベクトルが必要なので、openssl関数を使用して初期ベクトルを生成します。変数$strong
は、生成されたIVが暗号的に強力かどうかを判断するために使用されます。
暗号化
$method = "aes-256-cbc"; // cipher method
$iv_length = openssl_cipher_iv_length($method); // obtain required IV length
$strong = false; // set to false for next line
$iv = openssl_random_pseudo_bytes($iv_length, $strong); // generate initialization vector
/* NOTE: The IV needs to be retrieved later, so store it in a database.
However, do not reuse the same IV to encrypt the data again. */
if(!$strong) { // throw exception if the IV is not cryptographically strong
throw new Exception("IV not cryptographically strong!");
}
$data = "This is a message to be secured."; // Our secret message
$pass = "Stack0verfl0w"; // Our password
/* NOTE: Password should be submitted through POST over an HTTPS session.
Here, it's being stored in a variable for demonstration purposes. */
$enc_data = openssl_encrypt($data, $method, $password, true, $iv); // Encrypt
復号化
/* Retrieve the IV from the database and the password from a POST request */
$dec_data = openssl_decrypt($enc_data, $method, $pass, true, $iv); // Decrypt
Base64エンコードとデコード
暗号化されたデータを印刷可能なテキストで送信または格納する必要がある場合は、 base64_encode()
およびbase64_decode()
関数を使用する必要があります。
/* Base64 Encoded Encryption */
$enc_data = base64_encode(openssl_encrypt($data, $method, $password, true, $iv));
/* Decode and Decrypt */
$dec_data = openssl_decrypt(base64_decode($enc_data), $method, $password, true, $iv);
OpenSSLを使用した大容量ファイルの対称暗号化と復号化
PHPには大きなファイルを暗号化して解読するためのビルドイン機能がありません。 openssl_encrypt
は文字列を暗号化するために使用できますが、巨大なファイルをメモリにロードすることは悪い考えです。
だから、それを行うユーザランド関数を書く必要があります。この例では、対称AES-128-CBCアルゴリズムを使用して、大きなファイルの小さなチャンクを暗号化し、別のファイルに書き込みます。
ファイルを暗号化する
/**
* Define the number of blocks that should be read from the source file for each chunk.
* For 'AES-128-CBC' each block consist of 16 bytes.
* So if we read 10,000 blocks we load 160kb into memory. You may adjust this value
* to read/write shorter or longer chunks.
*/
define('FILE_ENCRYPTION_BLOCKS', 10000);
/**
* Encrypt the passed file and saves the result in a new file with ".enc" as suffix.
*
* @param string $source Path to file that should be encrypted
* @param string $key The key used for the encryption
* @param string $dest File name where the encryped file should be written to.
* @return string|false Returns the file name that has been created or FALSE if an error occured
*/
function encryptFile($source, $key, $dest)
{
$key = substr(sha1($key, true), 0, 16);
$iv = openssl_random_pseudo_bytes(16);
$error = false;
if ($fpOut = fopen($dest, 'w')) {
// Put the initialzation vector to the beginning of the file
fwrite($fpOut, $iv);
if ($fpIn = fopen($source, 'rb')) {
while (!feof($fpIn)) {
$plaintext = fread($fpIn, 16 * FILE_ENCRYPTION_BLOCKS);
$ciphertext = openssl_encrypt($plaintext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
// Use the first 16 bytes of the ciphertext as the next initialization vector
$iv = substr($ciphertext, 0, 16);
fwrite($fpOut, $ciphertext);
}
fclose($fpIn);
} else {
$error = true;
}
fclose($fpOut);
} else {
$error = true;
}
return $error ? false : $dest;
}
ファイルの復号化
上記の関数で暗号化されたファイルを復号化するには、この関数を使用できます。
/**
* Dencrypt the passed file and saves the result in a new file, removing the
* last 4 characters from file name.
*
* @param string $source Path to file that should be decrypted
* @param string $key The key used for the decryption (must be the same as for encryption)
* @param string $dest File name where the decryped file should be written to.
* @return string|false Returns the file name that has been created or FALSE if an error occured
*/
function decryptFile($source, $key, $dest)
{
$key = substr(sha1($key, true), 0, 16);
$error = false;
if ($fpOut = fopen($dest, 'w')) {
if ($fpIn = fopen($source, 'rb')) {
// Get the initialzation vector from the beginning of the file
$iv = fread($fpIn, 16);
while (!feof($fpIn)) {
$ciphertext = fread($fpIn, 16 * (FILE_ENCRYPTION_BLOCKS + 1)); // we have to read one block more for decrypting than for encrypting
$plaintext = openssl_decrypt($ciphertext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
// Use the first 16 bytes of the ciphertext as the next initialization vector
$iv = substr($ciphertext, 0, 16);
fwrite($fpOut, $plaintext);
}
fclose($fpIn);
} else {
$error = true;
}
fclose($fpOut);
} else {
$error = true;
}
return $error ? false : $dest;
}
使い方
これがどのように機能するかを調べたり、上記の関数をテストするには小さなスニペットが必要な場合は、次のコードを見てください。
$fileName = __DIR__.'/testfile.txt';
$key = 'my secret key';
file_put_contents($fileName, 'Hello World, here I am.');
encryptFile($fileName, $key, $fileName . '.enc');
decryptFile($fileName . '.enc', $key, $fileName . '.dec');
これで3つのファイルが作成されます:
- testfile.txtとプレーンテキスト
- 暗号化されたファイルでtestfile.txt.enc
- testfile.txt.decを復号化されたファイルで置き換えます。これはtestfile.txtと同じ内容でなければなりません