- vừa được xem lúc

Tìm hiểu mã hóa, giải mã, các thuật toán mã hóa - Phần 2 - Demo thuật toán mã hóa AES

0 0 262

Người đăng: Le Duc Son

Theo Viblo Asia

Ở phần này thì mình sẽ demo về thuật toán mã hóa Advanced Encryption Standard VD này sẽ sử dụng dựa trên ngôn ngữ Ruby. Ruby thì nó hỗ trợ cho chúng ta các thuật toán để việc viết code nhanh hơn

Chúng ta sẽ sử dụng module Cipher của thư viện 'openssl' được cung cấp mặc định trong ruby để phục vụ cho việc viết code của chúng ta

Chúng ta sẽ tạo hàm để mã hóa dữ liệu

def encrypt password, salt, data key = key_generator(password, salt) cipher = OpenSSL::Cipher.new('AES-128-CBC') cipher.encrypt cipher.key = key iv = cipher.random_iv encrypted = cipher.update(data) + cipher.final return {iv: iv, data: encrypted} end
  • Thuât toán mã hóa được sử dụng là AES-128-CBC. Ví dụ ở đây ta dùng thuật toán mã hóa đối xứng AES với chiều dài khóa 128 bit, dùng CBC mode. Để biết các thuật toán được openssl cung cấp ta có thể dùng hàm OpenSSL::Cipher.ciphers
  • key: khóa dùng để mã hóa/giải mã.
  • iv: vector khởi tạo(initialization vector)

Trong đoạn code trên khóa giải mã và vector đều được tạo random, mã này phải được lưu ở đâu đấy sau này dùng để giải mã lại. Đề phòng trường hợp quên thì mình sinh ra khóa từ một chuỗi password, mỗi khi cần giải mã chỉ cần nhập chuỗi password này vào là có thể lấy lại được văn bản ban đầu truyền vào.

Chúng ta sẽ dùng module PKCS5 để sinh khóa từ 1 password cho trước

def key_generator(password, salt, key_length = 16) iter = 20000 key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(password, salt, iter, key_length) return key end
  • password: password dùng để tạo khóa.
  • salt: chuỗi salt được append vào password trước khi hash(dùng chống dictionary attack)
  • iter giá trị càng lớn thời gian sinh key sẽ càng lâu(điều này sẽ chống brute force attack)
  • key_length chiều dài khóa được sinh ra(128 bit), phải tương thích với thuật toán mã hóa(trong ví dụ trên là thuật AES 128 bit)

Sử dụng hàm trên đã có thể mã hóa được rồi, giờ ta sẽ tạo hàm dùng để giải mã

Tạo hàm giải mã

def decrypt(password, salt, iv, encrypted_data) key = key_generator(password, salt) decipher = OpenSSL::Cipher::AES.new(128, :CBC) decipher.decrypt decipher.key = key decipher.iv = iv plain = decipher.update(encrypted_data) + decipher.final return plain
end

Hàm giải mã chúng ta truyền vào password, chuỗi salt và iv (vector) được tạo ra khi mã hóa dữ liệu, encrypted_data là chuỗi text đã được mã hóa Khi giải mã ta cũng sẽ generator ra chuỗi key giống như khi mã hóa để sử dụng

Giờ ta sẽ chạy thử hàm mã hóa và giải mã trên

Trước hết sẽ chạy hàm mã hóa

salt = OpenSSL::Random.random_bytes(16)
password = "123456789"
data = "Xin chào, tôi là Sơn, chào mừng đến với Ruby"
encrypted_data = AesDemo.new.encrypt(password, salt, data)
puts "#{encrypted_data}\n"
  • password là mk mình dùng để gen khóa
  • data là chuỗi text mình cần mã hóa

Đây là thông tin chuỗi text sau khi được mã hóa

{:iv=>"\xEEs\xB4\xEA\x92xU+a0\xE7\x89\x13\x96\x8A\xF5", :data=>"\x0E8\xC2I\x0E\xD6\xD2g\xD2\xD4\x94\xD11J\xCE^'d\xDF\xA5\b\xAD\xAE\x17\xCD7\xBEO\n\xEDeJ\xA3K\\+\a\xFC\xC7\xCCp\xC3\xC7\x9A\x9A\xAF\xDF4'\xD2\x01\x8F\x15=\xC3\xD6\x8A\xDE\xCBJ\xC8\xD0\x80a"}

Giờ dùng password, chuỗi salt đã tạo ở phía trên và mã iv(vector) sau khi chạy hàm mã hóa để giải mã chuỗi text đó ngược lại

decrypted_data = AesDemo.new.decrypt(password, salt, encrypted_data[:iv], encrypted_data[:data])
puts decrypted_data

kết quả là

Xin chào, tôi là Newbe, chào mừng đến với Ruby

Đúng là chuỗi text ban đầu của mình

Đây là code full của vd trên

require 'openssl' class AesDemo def encrypt password, salt, data key = key_generator(password, salt) cipher = OpenSSL::Cipher.new('AES-128-CBC') cipher.encrypt cipher.key = key iv = cipher.random_iv encrypted = cipher.update(data) + cipher.final return {iv: iv, data: encrypted} end def decrypt(password, salt, iv, encrypted_data) key = key_generator(password, salt) decipher = OpenSSL::Cipher::AES.new(128, :CBC) decipher.decrypt decipher.key = key decipher.iv = iv plain = decipher.update(encrypted_data) + decipher.final return plain end def key_generator(password, salt, key_length = 16) iter = 20000 key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(password, salt, iter, key_length) return key end
end salt = OpenSSL::Random.random_bytes(16)
password = "123456789"
data = "Xin chào, tôi là Sơn, chào mừng đến với Ruby"
encrypted_data = AesDemo.new.encrypt(password, salt, data)
puts "#{encrypted_data}\n" decrypted_data = AesDemo.new.decrypt(password, salt, encrypted_data[:iv], encrypted_data[:data])
puts decrypted_data

Kết

Trên đây mình đã demo mã hóa và giải mã AES sử dụng thư viện openssl trong ruby. Ở bài sau mình sẽ demo vd về 1 loại thuật toán mã hóa khác

Bình luận

Bài viết tương tự

- vừa được xem lúc

Mã hóa đối xứng - Phần 1: Feistel và DES

Feistel. Feistel là một cấu trúc mã hóa khối được thiết kế bởi Horst Feistel và Don Coppersmith vào năm 1973.

0 0 22

- vừa được xem lúc

Giới thiệu về kĩ thuật tấn công AES-ECB Oracle

Trong bảo mật thông tin, việc hiểu rõ các phương thức mã hóa và cách chúng có thể bị tấn công là vô cùng quan trọng. Một trong những kỹ thuật tấn công phổ biến và dễ hiểu là tấn công AES ECB Oracle.

0 0 15

- vừa được xem lúc

Symmetric ciphers - Mật mã đối xứng AES (phần 4)

III. Thuật toán AES - thực hiện (tiếp). 7. MixColumns (tiếp).

0 0 8

- vừa được xem lúc

Symmetric ciphers - Mật mã đối xứng AES (phần 5)

IV. Thuật toán AES - hoàn thiện. 1. Xây dựng hàm mã hóa và giải mã.

0 0 8

- vừa được xem lúc

Symmetric ciphers - Mật mã đối xứng AES (phần 7)

VI. Mode CBC (Cipher Block Chaining) trong Block cipher và AES (tiếp). 2. Challenge CTF.

0 0 10

- vừa được xem lúc

Symmetric ciphers - Mật mã đối xứng AES (phần 8)

VIII. CBC bitflipping attacks. 1. Điểm yếu của vector khởi tạo iv.

0 0 12