วันเสาร์ที่ 1 ธันวาคม พ.ศ. 2561

เรื่องความปลอดภัยทีได้ไปลองมา

1 ลองแบบ 
PBKDF2 Password-based Encryption

ทางฝั่ง เข้ารหัส

message = "<note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note>"
cipher = OpenSSL::Cipher.new 'AES-128-CBC'
cipher.encrypt
iv = cipher.random_iv
pwd = 'admin123456'
salt = OpenSSL::Random.random_bytes 16
iter = 20000
key_len = cipher.key_len
digest = OpenSSL::Digest::SHA256.new
key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
cipher.key = key
encrypted = cipher.update message
encrypted << cipher.final

ทางฝั่ง ถอดรหัส

cipher = OpenSSL::Cipher.new 'AES-128-CBC'
cipher.decrypt
cipher.iv = iv # the one generated with #random_iv
pwd = 'admin123456'
salt = ??
iter = 20000
key_len = cipher.key_len
digest = OpenSSL::Digest::SHA256.new
key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
cipher.key = key
decrypted = cipher.update encrypted
decrypted << cipher.final

โดย จะต้องใช้กุญแจ ตัวเดียวกัน คือมี password ที่เหมือนกัน iterator เหมือนกัน salt เหมือนกัน

หรือก็คือ เป็น กุญแจแบบสมมาตร

ผลลัพธ์จากการถอดรหัสและเข้ารหัส



สามารถถอดได้ตามปกติ

-----------------------------------------------------

2 ลองแบบ กุญแจไม่สมมาตร มี กุญแจสาธารณะ และ กุญแจส่วนตัว

โดยอยู่บนเครื่องเดียวกัน

เริ่มจากการสร้าง กุญแจ มา 1 คู่ก่อน แล้วเก็บใน text .pem

require 'openssl'
key = OpenSSL::PKey::RSA.new 2048
open 'private_key.pem', 'w' do |io| io.write key.to_pem end
open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end

จะได้ไฟล์มาดังนี้


จากนั้นทางฝั่ง ผู้ส่ง ที่จำลองขึ้นมาจะมีโค้ดดังนี้

public_key = OpenSSL::PKey::RSA.new(File.read('public_key.pem'))
message = "<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>"
encrypt = public_key.public_encrypt message
p encrypt
open 'encrypt.txt', 'w' do |l| l.write encrypt end

โดยจะดึงกุญแจสาธารณะ มาใช้ในการเข้ารหัสข้อความ แล้วเก็บใน text เสมือน ส่งออกไป


ข้อความประมาณนี้


���:�+�ID�(�*��%"j;D4�>}�11N�j�Zz��d�t.�/���J|��4�l�Q�Yg�6
sO)�R�WA�Wt�){�X-W��.�V���q7T�s\�Vxk�l��q�]�[�pV,��� �W%��2kz��HJ���������b=�T�t:���L�\��O�hj��"�����9d_����"-
�*B2�j:ϩ�]�*- �%�\� �#���]�
D�F����^)�˻����
�xo�


จากนั้น ทำการให้ฝั่งผู้รับ ถอดรหัสโดยใช้โค้ดดังนี้

private_key = OpenSSL::PKey::RSA.new(File.read('private_key.pem'))
encrypt = File.read('encrypt.txt')
decrypt = private_key.private_decrypt encrypt
ดึงข้อความจากไฟล์มาเสมือนได้รับแล้ว ใช้กุญแจส่วนตัวที่เป็นคู่กันกับที่ส่งมา ถอดรหัส

จะได้ข้อความที่ถูกต้อง

** กุญแจจะมีลักษณะประมาณนี้



----------------------------------------------------------------------------------------------------------------

3 ต่อมาเรื่อง signature

ใช้ private key เข้ารหัส แล้วใช้ public key ถอดออกมาเพื่อยืนยันว่า ถูกส่งมาจากเจ้าของจริงๆ
เนื่องจากถ้าใช้ key ที่ไม่ใช่คู่กันจะถอดไม่ได้

http://ruby-doc.org/stdlib-2.5.3/libdoc/openssl/rdoc/OpenSSL.html

โค้ดฝั่งผู้ส่ง


private_key = OpenSSL::PKey::RSA.new(File.read('private_key.pem'))
message = "<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>"
digest = OpenSSL::Digest::SHA256.new
signature = private_key.sign digest, message
open 'signature.txt', 'w' do |l| l.write signature end
สร้างไฟล์ signature ที่ถูกเข้ารหัสข้อความด้วย private key เสมือนส่งออกไป




แล้วทางฝั่งรับ ก็อ่านไฟล์ แล้วแก้ออกมาเช็คว่าตรงกับข้อความเดิมมั้ย

public_key = OpenSSL::PKey::RSA.new(File.read('public_key.pem'))
digest = OpenSSL::Digest::SHA256.new
signature = File.read('signature.txt')

if public_key.verify digest, signature, message
puts 'Valid'
else
puts 'Invalid'
end

ได้ผลลัพธ์คือ ถูกต้อง



ซึ่งถือว่า เช็คได้ว่าถูกส่งมาจาก key คู่เดียวกันจริงๆ

----------------------------------------------------------------------------------
 

ไม่มีความคิดเห็น:

แสดงความคิดเห็น