Blockchain 03: Chữ ký điện tử

Đây là bài trong chuỗi bài về công nghệ blockchain.

Chữ ký điện tử (digital signatures) là công cụ mật mã học (crytographic primitive) được sử dụng rất nhiều trong công nghệ blockchain; chữ ký điện tử và hàm hash là nền tảng cơ bản mà blockchain sử dụng.

Mật mã hóa Khóa công khai (Public-key Cryptography)

Chữ ký điện tử (digital signatures) cụ thể là chữ ký điện tử dùng trong blockchain được xây dựng trên hệ mật mã hóa khóa công khai (public-key crytpography) hay còn được gọi là mật mã hóa khóa bất đối xứng (asymmetrical crytography).

Hệ thống này sử dụng một cặp khóa mật mã (keys): khóa công khai (public key) được đưa ra cho mọi người biết (không cần giữu bí mật), và khóa cá nhân (private key) chỉ có chủ nhân (owner) mới biết (phải giữ bí mật). Để một người xử dụng hệ mật mã này, việc đầu tiên người đó sẽ dùng một thuật toán tạo khóa (key generation) G để tạo ra một cặp khóa mật mã  ký hiệu là (sk, pk)

Như ví dụ minh họa trên, thì sk sẽ là khóa bí mật của Alice, còn pk sẽ là khóa công khai của Alice.

Bây giờ Bob có thể gửi một thông điệp m đến cho Alice bằng cách dùng khóa công khai của Alice pk để mã hóa c \leftarrow E(m, pk), sao đó Bob gửi thông điệp đã được mã hóa c cho Alice. Alice muốn đọc được nội dung cả văn bản đã được mã hóa c thì sẽ dùng khóa bí mật (private key) của mình để giải mã m =D(c, sk). Người ta gọi đây là hệ mật mã hóa khóa bất đối xứng (asymetric) vì việc mã hóa E và giải mã D dùng hai khóa (keys) khác nhau.

Một hệ thống mã hóa dùng khóa công khai thì bao gồm 3 thuật toán chính (G, E, D): thuật toán sinh khóa (key generation) G, thuật toán mã hóa (encryption) E, và thuật toán giải mã (decryption) D. Với hệ thống mã hóa này thì với mọi thông điệp (message) m và mọi cặp khóa (sk, pk) được sinh ra bởi thuật toán G thì nếu ta dùng khóa bí mật sk để giải mã một nội dung được mã hóa bằng khóa công khai pk thì chúng ta sẽ phải có được nội dung gốc D_{sk}(E_{pk}(m)) = m.

Thực hành

Đoạn code dưới đây minh họa việc tạo ra cặp khóa dùng để mã hóa và giải mã dữ liệu như trên hình vẽ minh họa trên.

from binascii import hexlify
import pyelliptic

# SECP256k1 is the curve that Bitcoin uses
bob = pyelliptic.ECC(curve='secp256k1')
alice = pyelliptic.ECC(curve='secp256k1')

message = "Hello Alice!"
alice_pub_key = alice.get_pubkey()
ciphertext = bob.encrypt(message, alice_pub_key, ephemcurve='secp256k1')
print("Cipher Text: ",ciphertext)

decrypt_message = alice.decrypt(ciphertext)
print("Alice Decrypt: ", decrypt_message)

Thực ra trong hệ thống Bitcoin nói riêng và công nghệ blockchain nói chung, người ta không mã hóa thông tin nào cả như chúng ta sẽ thấy sau này. Trong công nghệ blockchain thì người ta dùng mật mã hóa công khai (public key crytography) để làm chữ ký điện tử (digital signatures).

Chữ ký Điện tử (Digital Signatures)

Chữ ký điện tử như cái tên của nó cho thấy là công cụ mật mã có những tính chất tương đồng như chữ ký tay ta vẫn dùng ngoài đời. Hai tính chất cơ bản của chữ ký điện tử là: Thứ nhất, chỉ có bạn mới có thể tạo ra chữ ký của bạn, nhưng bất kỳ ai nhìn thấy chữ ký đó đều có thể kiểm tra (verify) được chữ ký đó là  thật (valid). Thứ hai, chúng ta muốn một chữ ký phải gắn liền với một văn bản cụ thể, để chữ ký đó không thể được mang đi để ký một văn bản khác. Tương tự như chữ ký tay, chúng ta không muốn người ta cắt một chữ ký từ một hợp đồng này để dán sang một hợp đồng khác.

Một cách cụ thể, thì một hệ chữ ký điện tử (digital signature scheme) sẽ gồm có 3 thuật toán sau:

  • (s_k, p_k) := G(key_size) thuật toán tạo khóa G này giống như thuật toán tạo khóa đã đề cập ở trên.
  • sig := sign (s_k, m) thuật toán ký sẽ lấy đầu vào là một thông điệp m và mà khóa bí mật (private key) s_k, sau đó tạo ra chữ ký cho thông điệp  m dưới mã s_k.
  • verify(p_k, m, sig) thuật toán kiểm định chữ ký verify sẽ lấy đầu vào là một thông điệm m, một chữ ký sig, và một khóa công khai p_k. Thuật toán sẽ trả lại giá trị true nếu sig là chữ ký của thông điệp m dưới khóa public key p_k, trả lại giá trị  false nếu không phải.

Chúng ta đòi hỏi hệ chữ ký điện tử phải thỏa mãn 2 tính chất sau:

  • Chữ ký đúng thì phải được kiểm tra ra kết quả đúng: verify(p_k, m, sign(s_k, m)) == true
  • Chữ ký không thể bị giả mạo.

Tính chất đầu tiên rất hiển nhiên. Khi chúng ta ký (sign) một thông điệp m bằng chữ ký bí mật s_k, sau đó một người khác sử dụng chữ kỹ công khai p_k để kiểm tra (verify) chữ ký đó trên cùng một thông điệp m thì phải được trả lại kết quả đúng (true). Đây là đòi hỏi cơ bản nhất để chữ ký điện tử có thể được sử dụng.

Tính chất thứ hai có nghĩa là không có thuật toán hoặc phương tiện tính toán nào để tạo ra được chữ ký giả. Nếu một người khác biết được chữ ký công khai (public key) của chúng ta và nhìn thấy chữ ký của chúng ta trên một số thông điệp trước (messages), thì họ không thể giả mạo được chữ ký của chúng ta trên một thông điệp mà họ chưa thấy chữ ký của ta.

Thực hành 

Chúng ta có thể tiếp tục dùng thư viện Pyelliptic của Python để thực hành chữ ký điện tử.

from binascii import hexlify
import pyelliptic

# SECP256k1 is the curve that Bitcoin uses
bob = pyelliptic.ECC(curve='secp256k1')
alice = pyelliptic.ECC(curve='secp256k1')

alice_pub_key = alice.get_pubkey()
commitment = "Cho toi vay $500"
signature = alice.sign(commitment)
print("Check Signature: ", pyelliptic.ECC(pubkey=alice_pub_key,
 curve='secp256k1').verify(signature, commitment))

Leave a Reply