วิธีเข้ารหัส / ถอดรหัสข้อมูลใน php


110

ตอนนี้ฉันเป็นนักเรียนและฉันกำลังเรียน PHP ฉันกำลังพยายามเข้ารหัส / ถอดรหัสข้อมูลง่ายๆใน PHP ฉันทำการค้นคว้าทางออนไลน์และบางส่วนก็ค่อนข้างสับสน (อย่างน้อยก็สำหรับฉัน)

นี่คือสิ่งที่ฉันพยายามทำ:

ฉันมีตารางที่ประกอบด้วยฟิลด์เหล่านี้(UserID, Fname, Lname, Email, Password)

สิ่งที่ฉันต้องการคือมีการเข้ารหัสฟิลด์ทั้งหมดแล้วถอดรหัส (เป็นไปได้หรือไม่ที่จะใช้sha256สำหรับการเข้ารหัส / ถอดรหัสหากไม่มีอัลกอริทึมการเข้ารหัสใด ๆ )

สิ่งที่ฉันต้องการเรียนรู้อีกอย่างหนึ่งคือการสร้างทางเดียวhash(sha256)รวมกับ "เกลือ" ที่ดีได้อย่างไร (โดยพื้นฐานแล้วฉันแค่ต้องการใช้การเข้ารหัส / ถอดรหัสอย่างง่ายhash(sha256)+salt) เซอร์ / แหม่มคำตอบของคุณจะเป็นประโยชน์อย่างยิ่งและจะได้รับการชื่นชมมากขอบคุณ ++




9
SHA เป็นแฮชไม่ใช่การเข้ารหัส ประเด็นสำคัญคือแฮชไม่สามารถย้อนกลับไปยังข้อมูลเดิมได้ (ไม่ใช่เรื่องง่ายเลย) คุณอาจต้องการmcryptหรือถ้าไม่มีฉันขอแนะนำphpseclib - แม้ว่าสิ่งสำคัญคือต้องสังเกตว่าการนำ PHP บริสุทธิ์ไปใช้กับอะไรก็ตามที่เกี่ยวข้องกับคณิตศาสตร์ระดับต่ำจำนวนมากจะเป็น sloooooowww ... นั่นเป็นเหตุผลที่ฉันชอบ phpseclib เพราะ จะใช้ mcrypt ก่อนหากมีให้ใช้งานและกลับไปใช้ PHP เป็นทางเลือกสุดท้ายเท่านั้น
DaveRandom

7
โดยปกติคุณไม่ต้องการถอดรหัสรหัสผ่าน!
Ja͢ck

1
โดยพื้นฐานแล้วคุณไม่ควรคิดถึงการเข้ารหัสในระดับนี้คุณควรคิดถึงการควบคุมการเข้าถึงการรักษาความลับความสมบูรณ์และการพิสูจน์ตัวตน หลังจากนั้นตรวจสอบว่าคุณจะบรรลุเป้าหมายนี้ได้อย่างไรโดยอาจใช้การเข้ารหัสหรือการแฮชที่ปลอดภัย คุณอาจต้องการอ่าน PBKDF2 และ bcrypt / scrypt เพื่อทำความเข้าใจการแฮชรหัสผ่านที่ปลอดภัยและสิ่งที่คล้ายกัน
Maarten Bodewes

คำตอบ:


289

คำนำ

เริ่มต้นด้วยนิยามตารางของคุณ:

- UserID
- Fname
- Lname
- Email
- Password
- IV

การเปลี่ยนแปลงมีดังนี้

  1. เขตข้อมูลFname, LnameและEmailจะได้รับการเข้ารหัสโดยใช้การเข้ารหัสแบบสมมาตรให้โดยOpenSSL ,
  2. IVข้อมูลจะเก็บเวกเตอร์ initialisationใช้สำหรับการเข้ารหัส ข้อกำหนดในการจัดเก็บขึ้นอยู่กับการเข้ารหัสและโหมดที่ใช้ เพิ่มเติมเกี่ยวกับเรื่องนี้ในภายหลัง
  3. Passwordฟิลด์จะถกใช้ทางเดียวกัญชารหัสผ่าน

การเข้ารหัส

การเข้ารหัสและโหมด

การเลือกรหัสและโหมดการเข้ารหัสที่ดีที่สุดอยู่นอกเหนือขอบเขตของคำตอบนี้ แต่ตัวเลือกสุดท้ายมีผลต่อขนาดของทั้งคีย์การเข้ารหัสและเวกเตอร์การเริ่มต้น สำหรับโพสต์นี้เราจะใช้ AES-256-CBC ซึ่งมีขนาดบล็อกคงที่ 16 ไบต์และขนาดคีย์ 16, 24 หรือ 32 ไบต์

คีย์การเข้ารหัส

คีย์เข้ารหัสที่ดีคือ binary blob ที่สร้างจากตัวสร้างตัวเลขสุ่มที่เชื่อถือได้ ขอแนะนำตัวอย่างต่อไปนี้ (> = 5.3):

$key_size = 32; // 256 bits
$encryption_key = openssl_random_pseudo_bytes($key_size, $strong);
// $strong will be true if the key is crypto safe

ซึ่งสามารถทำได้ครั้งเดียวหรือหลายครั้ง (หากคุณต้องการสร้างชุดคีย์การเข้ารหัสลับ) ทำให้สิ่งเหล่านี้เป็นส่วนตัวมากที่สุด

IV

เวกเตอร์เริ่มต้นจะเพิ่มการสุ่มให้กับการเข้ารหัสและจำเป็นสำหรับโหมด CBC ควรใช้ค่าเหล่านี้เพียงครั้งเดียว (ในทางเทคนิคหนึ่งครั้งต่อคีย์การเข้ารหัส) ดังนั้นการอัปเดตส่วนใดส่วนหนึ่งของแถวควรสร้างใหม่

มีฟังก์ชันเพื่อช่วยคุณสร้าง IV:

$iv_size = 16; // 128 bits
$iv = openssl_random_pseudo_bytes($iv_size, $strong);

ตัวอย่าง

มาเข้ารหัสฟิลด์ชื่อโดยใช้ก่อนหน้านี้$encryption_keyและ$iv; ในการทำเช่นนี้เราต้องใส่ข้อมูลของเราให้มีขนาดบล็อก:

function pkcs7_pad($data, $size)
{
    $length = $size - strlen($data) % $size;
    return $data . str_repeat(chr($length), $length);
}

$name = 'Jack';
$enc_name = openssl_encrypt(
    pkcs7_pad($name, 16), // padded data
    'AES-256-CBC',        // cipher and mode
    $encryption_key,      // secret key
    0,                    // options (not used)
    $iv                   // initialisation vector
);

ข้อกำหนดในการจัดเก็บ

เอาต์พุตที่เข้ารหัสเช่น IV เป็นไบนารี การจัดเก็บค่าเหล่านี้ในฐานข้อมูลสามารถทำได้โดยใช้ประเภทคอลัมน์ที่กำหนดเช่นหรือBINARYVARBINARY

ค่าผลลัพธ์เช่น IV เป็นไบนารี ในการจัดเก็บค่าเหล่านั้นใน MySQL ให้พิจารณาใช้BINARYหรือVARBINARYคอลัมน์ หากนี่ไม่ใช่ตัวเลือกคุณยังสามารถแปลงข้อมูลไบนารีเป็นการแสดงข้อความโดยใช้base64_encode()หรือbin2hex()การทำเช่นนี้ต้องใช้พื้นที่เก็บข้อมูลเพิ่มขึ้นระหว่าง 33% ถึง 100%

การถอดรหัส

การถอดรหัสค่าที่เก็บไว้จะคล้ายกัน:

function pkcs7_unpad($data)
{
    return substr($data, 0, -ord($data[strlen($data) - 1]));
}

$row = $result->fetch(PDO::FETCH_ASSOC); // read from database result
// $enc_name = base64_decode($row['Name']);
// $enc_name = hex2bin($row['Name']);
$enc_name = $row['Name'];
// $iv = base64_decode($row['IV']);
// $iv = hex2bin($row['IV']);
$iv = $row['IV'];

$name = pkcs7_unpad(openssl_decrypt(
    $enc_name,
    'AES-256-CBC',
    $encryption_key,
    0,
    $iv
));

การเข้ารหัสที่พิสูจน์ตัวตน

คุณสามารถปรับปรุงความสมบูรณ์ของข้อความรหัสที่สร้างขึ้นเพิ่มเติมได้โดยการต่อท้ายลายเซ็นที่สร้างจากคีย์ลับ (ต่างจากคีย์เข้ารหัส) และข้อความเข้ารหัส ก่อนที่ข้อความรหัสจะถูกถอดรหัสลายเซ็นจะได้รับการตรวจสอบก่อน (ควรใช้วิธีการเปรียบเทียบเวลาคงที่)

ตัวอย่าง

// generate once, keep safe
$auth_key = openssl_random_pseudo_bytes(32, $strong);

// authentication
$auth = hash_hmac('sha256', $enc_name, $auth_key, true);
$auth_enc_name = $auth . $enc_name;

// verification
$auth = substr($auth_enc_name, 0, 32);
$enc_name = substr($auth_enc_name, 32);
$actual_auth = hash_hmac('sha256', $enc_name, $auth_key, true);

if (hash_equals($auth, $actual_auth)) {
    // perform decryption
}

ดูสิ่งนี้ด้วย: hash_equals()

แฮช

การจัดเก็บรหัสผ่านที่ย้อนกลับได้ในฐานข้อมูลของคุณจะต้องหลีกเลี่ยงให้มากที่สุด คุณต้องการตรวจสอบรหัสผ่านเท่านั้นแทนที่จะรู้เนื้อหา หากผู้ใช้ทำรหัสผ่านหายจะเป็นการดีกว่าที่จะอนุญาตให้รีเซ็ตได้แทนที่จะส่งรหัสเดิมมาให้ (ตรวจสอบให้แน่ใจว่าการรีเซ็ตรหัสผ่านทำได้ในระยะเวลา จำกัด เท่านั้น)

การใช้ฟังก์ชันแฮชเป็นการดำเนินการทางเดียว หลังจากนั้นสามารถใช้เพื่อการตรวจสอบได้อย่างปลอดภัยโดยไม่ต้องเปิดเผยข้อมูลต้นฉบับ สำหรับรหัสผ่านวิธี brute force เป็นวิธีการที่เป็นไปได้ในการเปิดเผยเนื่องจากความยาวค่อนข้างสั้นและตัวเลือกรหัสผ่านที่ไม่ดีสำหรับหลาย ๆ คน

อัลกอริทึมการแฮชเช่น MD5 หรือ SHA1 ถูกสร้างขึ้นเพื่อตรวจสอบเนื้อหาไฟล์กับค่าแฮชที่ทราบ พวกเขาได้รับการปรับให้เหมาะสมอย่างมากเพื่อให้การยืนยันนี้เร็วที่สุดในขณะที่ยังคงมีความถูกต้อง เนื่องจากพื้นที่เอาต์พุตที่ค่อนข้าง จำกัด จึงง่ายต่อการสร้างฐานข้อมูลด้วยรหัสผ่านที่รู้จักและเอาต์พุตแฮชตามลำดับตารางสายรุ้ง

การเพิ่มเกลือลงในรหัสผ่านก่อนที่จะแฮชจะทำให้ตารางสายรุ้งไร้ประโยชน์ แต่ความก้าวหน้าของฮาร์ดแวร์ล่าสุดทำให้การค้นหากำลังดุร้ายเป็นแนวทางที่ใช้ได้ผล นั่นเป็นเหตุผลที่คุณต้องมีอัลกอริทึมการแฮชที่ช้าโดยเจตนาและไม่สามารถปรับให้เหมาะสมได้ นอกจากนี้ยังควรจะสามารถเพิ่มภาระสำหรับฮาร์ดแวร์ที่เร็วขึ้นโดยไม่ส่งผลต่อความสามารถในการตรวจสอบแฮชรหัสผ่านที่มีอยู่เพื่อพิสูจน์ในอนาคต

ปัจจุบันมีสองตัวเลือกยอดนิยมให้เลือก:

  1. PBKDF2 (ฟังก์ชันการหาคีย์จากรหัสผ่าน v2)
  2. bcrypt (aka Blowfish)

คำตอบนี้จะใช้ตัวอย่างกับ bcrypt

เจนเนอเรชั่น

แฮชรหัสผ่านสามารถสร้างได้ดังนี้:

$password = 'my password';
$random = openssl_random_pseudo_bytes(18);
$salt = sprintf('$2y$%02d$%s',
    13, // 2^n cost factor
    substr(strtr(base64_encode($random), '+', '.'), 0, 22)
);

$hash = crypt($password, $salt);

เกลือจะถูกสร้างขึ้นด้วยopenssl_random_pseudo_bytes()ในรูปแบบหยดสุ่มของข้อมูลซึ่งดำเนินการแล้วผ่านbase64_encode()และเพื่อให้ตรงกับตัวอักษรที่จำเป็นของstrtr()[A-Za-z0-9/.]

crypt()ประสิทธิภาพการทำงานคร่ำเครียดอยู่บนพื้นฐานของอัลกอริทึม ( $2y$สำหรับปักเป้า) ปัจจัยต้นทุน (ปัจจัย 13 ใช้เวลาประมาณ 0.40s บนเครื่อง 3GHz) และเกลือของ 22 ตัวอักษร

การตรวจสอบ

เมื่อคุณดึงข้อมูลแถวที่มีข้อมูลผู้ใช้แล้วให้ตรวจสอบรหัสผ่านในลักษณะนี้:

$given_password = $_POST['password']; // the submitted password
$db_hash = $row['Password']; // field with the password hash

$given_hash = crypt($given_password, $db_hash);

if (isEqual($given_hash, $db_hash)) {
    // user password verified
}

// constant time string compare
function isEqual($str1, $str2)
{
    $n1 = strlen($str1);
    if (strlen($str2) != $n1) {
        return false;
    }
    for ($i = 0, $diff = 0; $i != $n1; ++$i) {
        $diff |= ord($str1[$i]) ^ ord($str2[$i]);
    }
    return !$diff;
}

ในการตรวจสอบรหัสผ่านคุณโทรcrypt()อีกครั้ง แต่คุณส่งแฮชที่คำนวณไว้ก่อนหน้านี้เป็นค่าเกลือ ค่าที่ส่งคืนจะให้แฮชเดียวกันหากรหัสผ่านที่กำหนดตรงกับแฮช ในการตรวจสอบแฮชมักแนะนำให้ใช้ฟังก์ชันเปรียบเทียบเวลาคงที่เพื่อหลีกเลี่ยงการโจมตีตามเวลา

การแฮชรหัสผ่านด้วย PHP 5.5

PHP 5.5 แนะนำฟังก์ชันการแฮชรหัสผ่านที่คุณสามารถใช้เพื่อลดความซับซ้อนของวิธีการแฮชข้างต้น:

$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 13]);

และตรวจสอบ:

if (password_verify($given_password, $db_hash)) {
    // password valid
}

ดูเพิ่มเติม: password_hash(),password_verify()


ฉันควรใช้ความยาวเท่าใดในการจัดเก็บชื่อนามสกุลอีเมลและอื่น ๆ เพื่อการเดิมพันที่ปลอดภัยที่สุด? varbinary (???)
BentCoder

2
แน่นอน แต่ขึ้นอยู่กับวิธีการใช้งาน หากคุณเผยแพร่ไลบรารีการเข้ารหัสคุณไม่รู้ว่านักพัฒนาจะนำไปใช้อย่างไร นั่นเป็นเหตุผลที่github.com/defuse/php-encryptionให้การเข้ารหัสคีย์สมมาตรที่ได้รับการรับรองความถูกต้องและไม่อนุญาตให้นักพัฒนาทำให้อ่อนแอลงโดยไม่ต้องแก้ไขโค้ด
Scott Arciszewski

2
@Scott ดีมากฉันได้เพิ่มตัวอย่างของการเข้ารหัสที่รับรองความถูกต้อง ขอบคุณสำหรับการผลักดัน :)
Ja͢ck

1
+1 สำหรับการเข้ารหัสที่พิสูจน์ตัวตน คำถามมีข้อมูลไม่เพียงพอที่จะบอกว่าที่นี่ไม่จำเป็นต้องใช้ AE แน่นอนว่าการรับส่งข้อมูล SQL มักจะผ่านเครือข่ายที่มีคุณสมบัติด้านความปลอดภัยที่ไม่รู้จักเช่นเดียวกับการรับส่งข้อมูลจากฐานข้อมูลไปยังหน่วยเก็บ การสำรองข้อมูลและการจำลองแบบด้วย รูปแบบภัยคุกคามคืออะไร? คำถามไม่ได้บอกไว้และอาจเป็นอันตรายหากตั้งสมมติฐาน
Jason Orendorff

1
แทนที่จะใช้ฮาร์ดโค้ด$iv_size = 16;ฉันจะใช้: $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("AES-256-CBC"))เพื่อระบุความเชื่อมโยงระหว่างขนาดของ iv ที่จะใช้กับการเข้ารหัสที่ใช้ นอกจากนี้คุณยังสามารถขยายความต้องการ (หรือไม่) ของpkcs7_pad()/ pkcs7_unpad()หรือทำให้โพสต์ง่ายขึ้นโดยการกำจัดออกและใช้ "aes-256-ctr" Great post @ Ja͢ck
Patrick Allaert

24

ฉันคิดว่าได้รับคำตอบก่อนหน้านี้ ... แต่อย่างไรก็ตามหากคุณต้องการเข้ารหัส / ถอดรหัสข้อมูลคุณจะใช้ SHA256 ไม่ได้

//Key
$key = 'SuperSecretKey';

//To Encrypt:
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, 'I want to encrypt this', MCRYPT_MODE_ECB);

//To Decrypt:
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, MCRYPT_MODE_ECB);

7
คุณไม่ควรใช้ ECB เช่นกันสำหรับเรื่องนั้น
Maarten Bodewes

7
คีย์ควรเป็นไบต์แบบสุ่มหรือคุณควรใช้ฟังก์ชันการหาคีย์ที่ปลอดภัย
Maarten Bodewes

4
MCRYPT_RIJNDAEL_256 ไม่ใช่ฟังก์ชันมาตรฐานคุณควรใช้ AES (MCRYPT_RIJNDAEL_128)
Maarten Bodewes

14

ตอบความเป็นมาและคำอธิบาย

เพื่อให้เข้าใจคำถามนี้ก่อนอื่นคุณต้องเข้าใจว่า SHA256 คืออะไร SHA256 เป็นฟังก์ชั่นการเข้ารหัสลับแฮ Cryptographic Hash Function เป็นฟังก์ชันทางเดียวซึ่งเอาต์พุตมีความปลอดภัยในการเข้ารหัส ซึ่งหมายความว่าง่ายต่อการคำนวณแฮช (เทียบเท่ากับการเข้ารหัสข้อมูล) แต่ยากที่จะรับอินพุตดั้งเดิมโดยใช้แฮช (เทียบเท่ากับการถอดรหัสข้อมูล) เนื่องจากการใช้ฟังก์ชันแฮชการเข้ารหัสหมายความว่าการถอดรหัสลับเป็นไปไม่ได้ในเชิงคำนวณดังนั้นคุณจึงไม่สามารถถอดรหัสด้วย SHA256 ได้

สิ่งที่คุณต้องการที่จะใช้ฟังก์ชั่นแบบสองทาง แต่มากขึ้นโดยเฉพาะการบล็อก Cipher ฟังก์ชันที่ช่วยให้สามารถเข้ารหัสและถอดรหัสข้อมูลได้ ฟังก์ชันmcrypt_encryptและmcrypt_decryptโดยค่าเริ่มต้นจะใช้อัลกอริทึม Blowfish การใช้ mcrypt ของ PHP สามารถพบได้ในคู่มือนี้ รายการคำจำกัดความของการเข้ารหัสเพื่อเลือกใช้ mcrypt การเข้ารหัสยังมีอยู่ วิกิพีเดียในปักเป้าสามารถพบได้ที่วิกิพีเดีย การเข้ารหัสบล็อกจะเข้ารหัสอินพุตในบล็อกที่มีขนาดและตำแหน่งที่ทราบด้วยคีย์ที่ทราบเพื่อให้สามารถถอดรหัสข้อมูลได้ในภายหลังโดยใช้คีย์ นี่คือสิ่งที่ SHA256 ไม่สามารถให้คุณได้

รหัส

$key = 'ThisIsTheCipherKey';

$ciphertext = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, 'This is plaintext.', MCRYPT_MODE_CFB);

$plaintext = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $encrypted, MCRYPT_MODE_CFB);

คุณไม่ควรใช้ ECB เช่นกันสำหรับเรื่องนั้น
Maarten Bodewes

คีย์ควรเป็นไบต์แบบสุ่มหรือคุณควรใช้ฟังก์ชันการหาคีย์ที่ปลอดภัย
Maarten Bodewes

4
ไม่เคยใช้โหมด ECB มันไม่ปลอดภัยและส่วนใหญ่ไม่ได้ช่วยในการเข้ารหัสข้อมูลจริงๆ (แทนที่จะเข้ารหัสข้อมูลเท่านั้น) ดูบทความ Wikipedia ที่ยอดเยี่ยมในหัวข้อนี้สำหรับข้อมูลเพิ่มเติม
Holger Just

1
ที่ดีที่สุดคือไม่ใช้ mcrypt ซึ่งเป็นละทิ้งไม่ได้รับการอัปเดตมาหลายปีแล้วและไม่รองรับการเพิ่มมาตรฐาน PKCS # 7 (née PKCS # 5) มีเพียงช่องว่างที่ไม่เป็นมาตรฐานที่ไม่สามารถใช้กับข้อมูลไบนารีได้ . mcrypt มีข้อบกพร่องที่โดดเด่นมากมายย้อนหลังไปถึงปี 2003 .. แทนที่จะพิจารณาใช้กลบเกลื่อนแต่จะได้รับการบำรุงรักษาและถูกต้อง
zaph

9

นี่คือตัวอย่างการใช้ openssl_encrypt

//Encryption:
$textToEncrypt = "My Text to Encrypt";
$encryptionMethod = "AES-256-CBC";
$secretHash = "encryptionhash";
$iv = mcrypt_create_iv(16, MCRYPT_RAND);
$encryptedText = openssl_encrypt($textToEncrypt,$encryptionMethod,$secretHash, 0, $iv);

//Decryption:
$decryptedText = openssl_decrypt($encryptedText, $encryptionMethod, $secretHash, 0, $iv);
print "My Decrypted Text: ". $decryptedText;

2
แทนที่จะmcrypt_create_iv()ใช้: openssl_random_pseudo_bytes(openssl_cipher_iv_length($encryptionMethod))วิธีนี้วิธีการทำงานสำหรับค่าใด ๆ ของ $ encryptionMethod และจะใช้ส่วนขยาย openssl เท่านั้น
Patrick Allaert

รหัสข้างต้นผลตอบแทนสำหรับfalse openssl_decrypt()โปรดดูstackoverflow.com/q/41952509/1066234 เนื่องจากการเข้ารหัสบล็อกเช่น AES ต้องการข้อมูลอินพุตเพื่อให้เป็นตัวคูณที่แน่นอนของขนาดบล็อก (16 ไบต์สำหรับ AES) เป็นสิ่งจำเป็น
Kai Noack

6
     function my_simple_crypt( $string, $action = 'e' ) {
        // you may change these values to your own
        $secret_key = 'my_simple_secret_key';
        $secret_iv = 'my_simple_secret_iv';

        $output = false;
        $encrypt_method = "AES-256-CBC";
        $key = hash( 'sha256', $secret_key );
        $iv = substr( hash( 'sha256', $secret_iv ), 0, 16 );

        if( $action == 'e' ) {
            $output = base64_encode( openssl_encrypt( $string, $encrypt_method, $key, 0, $iv ) );
        }
        else if( $action == 'd' ){
            $output = openssl_decrypt( base64_decode( $string ), $encrypt_method, $key, 0, $iv );
        }

        return $output;
    }

ง่ายมาก ! ฉันใช้มันสำหรับการเข้ารหัส - ถอดรหัสส่วน URL ขอบคุณ
Mahbub Tito

0

ฉันใช้เวลาพอสมควรในการคิดหาวิธีที่จะไม่ได้รับfalseเมื่อใช้งานopenssl_decrypt()และเข้ารหัสและถอดรหัสการทำงาน

    // cryptographic key of a binary string 16 bytes long (because AES-128 has a key size of 16 bytes)
    $encryption_key = '58adf8c78efef9570c447295008e2e6e'; // example
    $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
    $encrypted = openssl_encrypt($plaintext, 'aes-256-cbc', $encryption_key, OPENSSL_RAW_DATA, $iv);
    $encrypted = $encrypted . ':' . base64_encode($iv);

    // decrypt to get again $plaintext
    $parts = explode(':', $encrypted);
    $decrypted = openssl_decrypt($parts[0], 'aes-256-cbc', $encryption_key, OPENSSL_RAW_DATA, base64_decode($parts[1])); 

หากคุณต้องการส่งสตริงที่เข้ารหัสผ่าน URL คุณต้อง urlencode สตริง:

    $encrypted = urlencode($encrypted);

เพื่อทำความเข้าใจสิ่งที่เกิดขึ้นให้ดีขึ้นอ่าน:

ในการสร้างคีย์แบบยาว 16 ไบต์คุณสามารถใช้:

    $bytes = openssl_random_pseudo_bytes(16);
    $hex = bin2hex($bytes);

หากต้องการดูข้อความแสดงข้อผิดพลาดของ openssl คุณสามารถใช้: echo openssl_error_string();

หวังว่าจะช่วยได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.