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

Mật mã RSA - phần 3

0 0 1

Người đăng: Viblo Security

Theo Viblo Asia

III. Mật mã RSA - thực hiện (tiếp)

4. Sinh số nguyên tố trong Python

Bước đầu tiên để tạo ra một cặp khóa public key và private key là lựa chọn cặp số nguyên tố (p,q)(p, q), chúng sẽ đóng vai trò nền tảng cho tất cả các bước tạo khóa phía sau. Vậy thì, làm sao để tạo ra một cặp số nguyên tố (p,q)(p, q)?

Ngày trước, khi không có sự hỗ trợ của các công nghệ tiên tiến, người xưa đã "lưu lại" các số nguyên tố bằng cách sử dụng sàng Eratosthenes: lần lượt bỏ đi các hợp số là bội của các số nguyên tố và cuối cùng chỉ giữ lại các số nguyên tố.

Với ngôn ngữ Python, có thể sử dụng hàm getPrime() trong module Crypto.Util.number thuộc thư viện PyCryptodome:

getPrime(N:int, randfunc:callable): long

Hàm sẽ trả về một số nguyên tố ngẫu nhiên có độ dài NN bytes.

5. Module trong Python

Như đã tìm hiểu ở bài trước, cách mã hóa và giải mã trong mật mã RSA phần lớn làm việc với các phép tính Module - đồng dư thức. Chẳng hạn những phép tính như tìm số dư của số ABA^B trong module CC:

AB ?(modC)A^B \equiv\ ? \pmod {C}

Trong Python có thể sử dụng hàm pow(base, exponent, modulus) kết hợp tính toán số mũ và đồng dư, tương đương với (base ** exponent) % modulus, trong đó:

  • base là giá trị cơ số (số AA).
  • exponent là giá trị số mũ (số BB).
  • modulus là giá trị module (số CC).

Ví dụ tính kết quả 3718 ?(mod912)37^{18} \equiv\ ? \pmod {912}, chúng ta có chương trình đơn giản:

ans = pow(37, 18, 912)
print(ans)

Ngoài ra, khi hàm pow() không nhận argument thứ ba modulus sẽ trở thành một hàm tính kết quả lũy thừa. Khi chương trình cần tính toán số lượng phép toán lũy thừa nhiều và dữ liệu lớn, có thể thay thế bằng hàm math.pow() sẽ cải thiện tốc độ đáng kể. Thật vậy, sử dụng module timeit thực hiện kiểm tra thời gian hai hàm:

Có thể thấy ưu điểm vượt trội về thời gian của math.pow(), lý do là bởi vì khi chương trình được xử lý, hàm pow() sẽ tính toán dựa trên toán tử ** của Python, trong khi math.pow() dựa trên ngôn ngữ C cơ bản. Lưu ý rằng một nhược điểm của math.pow() không thể xử lý các số phức nhưng pow() có thể làm được điều đó, nên bạn đọc có thể cân nhắc sử dụng từng hàm trong mỗi trường hợp. Tham khảo thêm về bảng so sánh giá trị độ phức tạp thời gian và không gian:

Method Time Complexity Space Complexity
Looping Technique O(n) O(1)
** Operator O(Log(exponent)) O(1)
pow() function O(Log(exponent)) O(1)
math.pow() function O(1) O(1)

Quay lại bài tập 11 ở phần trước: Với khóa công khai n=943n=943e=7e=7, thông điệp mã hóa c=545c=545, số mũ bí mật d=503d=503 hãy tìm ra thông điệp gốc mm? Chúng ta có thể giải quyết dễ dàng bằng chương trình Python:

Bài tập dành cho bạn đọc: Cho cặp số nguyên tố (p,q)=(53,71)(p, q) = (53, 71), số mũ công khai e=65537e = 65537, hãy mã hóa số m=102m = 102.

6. Số nghịch đảo module - bài toán nghịch đảo module (Modular multiplicative inverse)

Khóa bí mật với số mũ bí mật dd cũng cần xác định nhằm giải mã thông điệp RSA.

Như chúng ta đã biết về cách xác định số mũ bí mật dd:

de1(modϕ(n))de\equiv 1 \pmod {\phi(n)}

Việc từ phương trình module này tìm ngược lại số dd còn được gọi là bài toán nghịch đảo module:

d1e(modϕ(n))d\equiv \frac{1}{e} \pmod {\phi(n)}

Trước hết chắc hẳn cần trả lời cho câu hỏi: Nếu biết trước cặp khóa công khai (n,e)(n, e), tức giá trị ee, ϕ(n)\phi(n) đã biết thì có tồn tại dd thỏa mãn phương trình trên không? Câu trả lời là có, chúng ta có thể dễ dàng chứng minh dựa vào mệnh đề: Nếu d=ƯCLN(a,b)d=\text{ƯCLN}(a, b) thì luôn tồn tại các số nguyên x,yx, y sao cho:

ax+by=dax+by=d

Quay lại phương trình module trên, do ƯCLN(e,ϕ(n))=1\text{ƯCLN}(e, \phi(n))=1 nên ta luôn tìm được số nguyên x,yx, y (chọn xx dương) sao cho:

ex+ϕ(n)y=1ex1(modϕ(n))ex + \phi(n)y=1\\ \rightarrow ex \equiv 1 \pmod {\phi(n)}

Chọn d=xd=x chính là giá trị cần tìm, chứng tỏ phương trình nghịch đảo module trên luôn giải được. Tiếp theo chúng ta cần giải quyết bài toán cách thức tìm ra dd.

Một cách đơn giản nhất đó là sử dụng vòng lặp thử tất cả trường hợp của dd bắt đầu từ 11, cho đến khi tìm được giá trị thỏa mãn phương trình module trên.

Xét ví dụ bài tập 22 ở phần trước: Với khóa công khai n=943n=943e=7e=7, thông điệp mã hóa c=545c=545, hãy tìm ra thông điệp gốc mm? Chúng ta cần tìm được số mũ bí mật dd khi biết (n,e)(n, e). Trước hết, có n=943=23×41=p×qn = 943 = 23 \times 41 = p \times q, nên ϕ(n)=22×40=880\phi(n)=22 \times 40 = 880. Chương trình tìm ra dd bằng cách thử tất cả trường hợp:

n = 943 # 943 = 23 x 41
p, q = 23, 41
e = 7 phi = (p-1) * (q-1) # Thử tất cả trường hợp của d
d = 1
while True: if (d * e - 1) % phi == 0: print(d) break d = d + 1

Tuy nhiên, việc sử dụng vòng lặp thử dần từng trường hợp của dd bắt đầu từ 11 thực sự gặp khó khăn với số nn lớn. Chẳng hạn, với cặp số (p,q)=(857504083339712752489993810777,1029224947942998075080348647219)(p, q) = (857504083339712752489993810777,1029224947942998075080348647219), chương trình có thể mất lượng thời gian rất lớn cho việc tìm ra dd khi mỗi vòng lặp chỉ tăng lên một đơn vị. Thay vào đó, chúng ta có thể tận dụng hàm pow() với exponent=-1de1(modϕ(n))d\equiv e^{-1} \pmod {\phi(n)}.

d = pow(e, -1, phi)

Áp dụng với cặp số nguyên tố lớn trên và e=65537e=65537, có thể nhanh chóng tính được số mũ bí mật dd:

Bên cạnh đó, module Crypto.Util.number cũng chứa hàm inverse() hỗ trợ tìm kiếm số nghịch đảo module ϕ(n)\phi(n) của số ee.

inverse(u:long, v:long): long

IV. Một số kỹ thuật tấn công n - phân tích số lớn ra tích hai thừa số nguyên tố

Trong mật mã RSA, chỉ có hai yếu tố được công khai là cặp số public key (n,e)(n, e). Khi attacker muốn giải mã được thông điệp mã hóa cc, họ buộc phải đồng thời có được số mũ bí mật ddϕ(n)\phi(n). Trong phần này chúng ta sẽ tập trung vào các phương pháp tìm ra ϕ(n)\phi(n), hay nói cách khác, cần tìm ra cặp số nguyên tố (p,q)(p, q), tức là giải quyết bài toán phân tích số nn ra tích hai thừa số nguyên tố.

1. Vấn đề khi lựa chọn cặp số nguyên tố (p,q)(p, q) nhỏ

Trước khi nói đến vấn đề an toàn, việc lựa chọn cặp số nguyên tố (p,q)(p, q) nhỏ sẽ dẫn tới nn nhỏ. Mật mã RSA được thực hiện dựa trên các phép toán module, nên chỉ có thể mã hóa thông điệp (sau khi chuyển đổi sang dạng dãy chữ số) nằm trong khoảng từ 00 tới n1n-1 (Trong trường không gian module của nn). Thật vậy:

Xét trường hợp mật mã RSA có khóa công khai (n,e)=(187,3)(n, e) = (187, 3), số mũ bí mật d=107d=107, chúng ta thử mã hóa một thông điệp lớn hơn khoảng module cho phép, m=255m=255. Ciphertext thu được:

c=me mod n=2553 mod 187=85c = m^e\ \ \text{mod}\ n = 255^3\ \ \text{mod}\ 187 =85

Khi giải mã ngược lại:

m=cd mod n=85107 mod 187=68m = c^d\ \ \text{mod}\ n = 85^{107}\ \ \text{mod}\ 187 = 68

Người nhận sẽ không thể tính ra chính xác thông điệp ban đầu, dẫn tới truyền tin thất bại. Như vậy, tích cặp số nguyên tố chọn ban đầu càng lớn, thì không gian thông điệp có thể mã hóa và truyền tải càng lớn.

Bên cạnh đó còn là vấn đề an toàn của mật mã, khi chọn cặp số nguyên tố sinh khóa nhỏ thì tỉ lệ bị attacker dựa vào khóa công khai tìm ra bộ số nguyên tố ban đầu là rất cao. Tính tới thời điểm 12/10/200912/10/2009, RSA với số nn có độ dài 768768 bit đã bị phân tích thành công (bạn đọc có thể tham khảo thêm tại đây).

Trong bối cảnh CTF, khi gặp challenge có số nn nhỏ, người chơi có thể dễ dàng phân tích thành tích các thừa số nguyên tố bằng nhiều cách. Chẳng hạn với số n=510143758735509025530880200653196460532653147n = 510143758735509025530880200653196460532653147 dài 150150 bit. Một số nền tảng online hỗ trở phân tích thành thừa số nguyên tố:

Bạn đọc có thể sử dụng một trong số các website factor online trên để giải quyết challenge Inferius Prime.

Tài liệu tham khảo

Bình luận

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

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

[Cryptopals] Set 8: Abstract Algebra (Challenge 63-66)

Đây là một bài trong series Cùng giải Cryptopals!.Các bạn nên tự làm hoặc vừa đọc vừa làm thay vì đọc lời giải trực tiếp. . Cẩn thận nhé, phần này rất rất dài, và khó hơn các phần trước rất nhiều.

0 0 47

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

Get Paid with Crypto in your App // Coinbase Commerce Tutorial

Learn how to accept cryptocurrency payments, like $BTC or $ETH, in your webapp with Coinbase Commerce. https://fireship.io/lessons/crypto-payments-web-firebase. .

0 0 53

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

Tản mạn về lỗ hổng trong smart contract của Fairmoon Token, các dấu hiệu bất thường và nguy cơ từ crypto

Hôm nay (19/05/2021) là một ngày đen tối đối với cộng đồng crypto khi:. .

0 0 69

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

Tạo mạng P2P trên blockchain và phát hành tiền điện tử của riêng bạn

Chào các bạn, trong bài viết Tự tạo Blockchain trong 60 dòng code Javascript , mình đã hướng dẫn cách tạo blockchain trong 60 dòng Javascript. Trong bài viết này, mình sẽ tạo bộ phận quan trọng nhất c

0 0 48

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

What happens if you hack 4.5 billion BTC? // The Code Report

Blockchain networks are virtually unhackable, but crypto exchanges not so much. In 2016, hackers stole 4.

0 0 29

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

Web5... The Web3 Killer?

Web5 is a new decentralized web framework based on the Bitcoin Lightning Network designed to replace Web3. . Resources. .

0 0 34