MỞ ĐẦU
Ngày nay rất nhiều người sử dụng ứng dụng Google Autheticator
( hay Authy
) trên smartphone để thực hiện xác thực 2 lớp
. Tuy nhiên làm thế nào mà kể cả chi không bật mạng, ứng dụng xác thực two bước này vẫn hoạt động bình là điều mình rất băn khoăn và đã thử research trên anh genitourinary Gồ ( lol )
Google Authenticator
là ứng dụng hiện thực hóa thuật toán Time-Based One-Time Password (TOTP)
. Nó bao gồm các thành phần sau :
- 1 khóa bí mật chia sẻ (shared secret – một dãy các byte)
- 1 đầu vào là thời gian hiện tại
- 1 hàm mã hóa
Shared Secret
Trước hết cần sử dụng một khóa bí mật để thiết lập tài khoản trên điện thoại. tantalum có thể chụp ảnh mã QR bằng điện thoại của mình hoặc có thể nhập theo cách thủ công. Trong trường hợp nhập thủ công, khóa bí mật của dịch vụ này được hiển thị theo định dạng sau :
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx |
---|
Mã QR chứa nominal tương tự là one url :
otpauth://totp/Google%3Ayourname@gmail.com?secret=xxxx&issuer=Google Input (Current time)
Giá trị remark đơn giản là thời giạn hiện tại của điện thoại của bạn, không cần có sự tương tác giữa client và waiter một chi đã có khóa bí mật. Tuy nhiên điều quan trọng là thời gian trên điện thoại phải trùng với thời gian trên waiter bởi waiter sẽ lặp lại chính xác những gì xảy radium tương tự trên điện thoại với input là thời gian hiện tại trên server .
Cụ thể hơn, waiter sẽ therefore sánh giá trị keepsake mà người dùng render với tất cả các token được sinh ra trong một khoảng thời gian nhất định ( vài chục giây đến vài phút ), nếu trùng nhau thì nominal bạn nhập là hợp lệ và pass qua vòng authentication thứ two .Signing Function
Hàm mã hóa được sử dụng ở đây là
HMAC-SHA1
. HMAC là viết tắt củaHash-based message authentication code
và nó là một thuật toán sử dụng hàm mã hóa một chiều ( trong trường hợp này là SHA1 ) để mã hóa giá trị .
Sử dụngHMAC
khá là associate in nursing toàn bởi chỉ chi có khóa bí mật mới sinh được cùng một giá trị end product cho cùng một giá trị input. Nghe thì phức tạp nhưng thuật toán thực tế thì đơn giản : | hmac = SHA1 ( secret + SHA1 ( unavowed + input ) ) |Algorithm
Trước hết tantalum cần base32 decode khóa bí mật. Vì google hiển thị khóa bí mật bao gồm cả dấu cách và bằng chữ in thường để dễ đọc, nên tantalum cần loại bỏ dấu cách và capital chúng lên :
Read more : Google Drive – Wikipedia
original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
Tiếp theo lấy input là thời gian hiện tại của hệ thống :
input = CURRENT_UNIX_TIME()
Một điều dễ nhận thấy ở google appraiser là mã sinh radium thường hợp lệ trong one khoảng thời gian nhất định trước chi lại sinh radium một giá trị mới. Nếu giá trị này thay đổi liên tục mỗi giây thì rất khó cho người dùng kịp đọc hay copy spread nó. Giá trị mặc định là thirty, lấy thời gian hiện tại chia cho thirty thì trong thirty giá trị stimulation là như nhau :
input = CURRENT_UNIX_TIME() / 30
Cuối cùng áp dụng hàm mã hóa
HMAC-SHA1
:original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret))) input = CURRENT_UNIX_TIME() / 30 hmac = SHA1(secret + SHA1(secret + input))
Cho đến thời điểm bây giờ, tantalum đã phần lớn hoàn thành dịch vụ xác thực two bước 2FA. Tuy nhiên kết quả tantalum thu được giá trị HMAC có độ dài tiêu chuẩn của một giá trị sau chi đi qua hàm mã hóa SHA1 ( twenty byte, forty ký tự hexa ) và chắc chả three-toed sloth muốn sử dụng dịch vụ này chi phải nhập forty ký tự cả. Khoảng six kí tự là vừa đẹp .
four_bytes = hmac[LAST_BYTE(hmac):LAST_BYTE(hmac) + 4]
tantalum có thể chuyển về dạng unsigned integer 32bit ( four byte )
Read more : 7 simple ways to use Google Translate
large_integer = INT(four_bytes)
Bây giờ thì tantalum đã chuyển giá trị sinh right ascension về bunco số rồi, tuy nhiên đây vẫn sẽ là số tương đối lớn ( 2^32 – one ). Để thu được bunco số nhỏ hơn, tantalum lấy giá trị thu được chia lấy dư cho one triệu :
large_integer = INT(four_bytes) small_integer = large_integer % 1,000,000
Cuối cùng, đoạn imposter code hoàn chỉnh :
original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
input = CURRENT_UNIX_TIME() / 30
hmac = SHA1(secret + SHA1(secret + input))
four_bytes = hmac[LAST_BYTE(hmac):LAST_BYTE(hmac) + 4]
large_integer = INT(four_bytes)
small_integer = large_integer % 1,000,000
KẾT LUẬN
Tài liệu tham khảo
hypertext transfer protocol : //garbagecollected.org/2014/09/14/how-google-authenticator-works/