- 密碼學教程
- 密碼學 - 首頁
- 密碼學 - 起源
- 密碼學 - 歷史
- 密碼學 - 原理
- 密碼學 - 應用
- 密碼學 - 優點與缺點
- 密碼學 - 現代
- 密碼學 - 傳統密碼
- 密碼學 - 加密的需求
- 密碼學 - 雙重強度加密
- 密碼系統
- 密碼系統
- 密碼系統 - 組成部分
- 密碼系統的攻擊
- 密碼系統 - 彩虹表攻擊
- 密碼系統 - 字典攻擊
- 密碼系統 - 暴力破解攻擊
- 密碼系統 - 密碼分析技術
- 密碼學的型別
- 密碼系統 - 型別
- 公鑰加密
- 現代對稱金鑰加密
- 密碼學雜湊函式
- 金鑰管理
- 密碼系統 - 金鑰生成
- 密碼系統 - 金鑰儲存
- 密碼系統 - 金鑰分發
- 密碼系統 - 金鑰吊銷
- 分組密碼
- 密碼系統 - 流密碼
- 密碼學 - 分組密碼
- 密碼學 - Feistel 分組密碼
- 分組密碼的工作模式
- 分組密碼的工作模式
- 電子密碼本 (ECB) 模式
- 密碼分組連結 (CBC) 模式
- 密碼反饋 (CFB) 模式
- 輸出反饋 (OFB) 模式
- 計數器 (CTR) 模式
- 經典密碼
- 密碼學 - 反向密碼
- 密碼學 - 凱撒密碼
- 密碼學 - ROT13 演算法
- 密碼學 - 換位密碼
- 密碼學 - 加密換位密碼
- 密碼學 - 解密換位密碼
- 密碼學 - 乘法密碼
- 密碼學 - 仿射密碼
- 密碼學 - 簡單替換密碼
- 密碼學 - 簡單替換密碼的加密
- 密碼學 - 簡單替換密碼的解密
- 密碼學 - 維吉尼亞密碼
- 密碼學 - 維吉尼亞密碼的實現
- 現代密碼
- Base64 編碼與解碼
- 密碼學 - XOR 加密
- 替換技術
- 密碼學 - 單字母替換密碼
- 密碼學 - 單字母替換密碼的破解
- 密碼學 - 多字母替換密碼
- 密碼學 - Playfair 密碼
- 密碼學 - 希爾密碼
- 多字母替換密碼
- 密碼學 - 一次性密碼本密碼
- 一次性密碼本密碼的實現
- 密碼學 - 換位技術
- 密碼學 - 柵欄密碼
- 密碼學 - 列置換密碼
- 密碼學 - 隱寫術
- 對稱演算法
- 密碼學 - 資料加密
- 密碼學 - 加密演算法
- 密碼學 - 資料加密標準
- 密碼學 - 三重 DES
- 密碼學 - 雙重 DES
- 高階加密標準
- 密碼學 - AES 結構
- 密碼學 - AES 變換函式
- 密碼學 - 位元組替換變換
- 密碼學 - 行移位變換
- 密碼學 - 列混淆變換
- 密碼學 - 輪金鑰加變換
- 密碼學 - AES 金鑰擴充套件演算法
- 密碼學 - Blowfish 演算法
- 密碼學 - SHA 演算法
- 密碼學 - RC4 演算法
- 密碼學 - Camellia 加密演算法
- 密碼學 - ChaCha20 加密演算法
- 密碼學 - CAST5 加密演算法
- 密碼學 - SEED 加密演算法
- 密碼學 - SM4 加密演算法
- IDEA - 國際資料加密演算法
- 公鑰(非對稱)密碼學演算法
- 密碼學 - RSA 演算法
- 密碼學 - RSA 加密
- 密碼學 - RSA 解密
- 密碼學 - 建立 RSA 金鑰
- 密碼學 - 破解 RSA 密碼
- 密碼學 - ECDSA 演算法
- 密碼學 - DSA 演算法
- 密碼學 - Diffie-Hellman 演算法
- 密碼學中的資料完整性
- 密碼學中的資料完整性
- 訊息認證
- 密碼學數字簽名
- 公鑰基礎設施
- 雜湊
- MD5(訊息摘要演算法 5)
- SHA-1(安全雜湊演算法 1)
- SHA-256(安全雜湊演算法 256 位)
- SHA-512(安全雜湊演算法 512 位)
- SHA-3(安全雜湊演算法 3)
- 雜湊密碼
- Bcrypt 雜湊模組
- 現代密碼學
- 量子密碼學
- 後量子密碼學
- 密碼學協議
- 密碼學 - SSL/TLS 協議
- 密碼學 - SSH 協議
- 密碼學 - IPsec 協議
- 密碼學 - PGP 協議
- 影像和檔案加密
- 密碼學 - 影像
- 密碼學 - 檔案
- 隱寫術 - 影像
- 檔案加密和解密
- 密碼學 - 檔案的加密
- 密碼學 - 檔案的解密
- 物聯網中的密碼學
- 物聯網安全挑戰、威脅和攻擊
- 物聯網安全的加密技術
- 物聯網裝置的通訊協議
- 常用的加密技術
- 自定義構建加密演算法(混合加密)
- 雲密碼學
- 量子密碼學
- 密碼學中的影像隱寫術
- DNA 密碼學
- 密碼學中的一次性密碼 (OTP) 演算法
- 區別
- 密碼學 - MD5 與 SHA1
- 密碼學 - RSA 與 DSA
- 密碼學 - RSA 與 Diffie-Hellman
- 密碼學與密碼學
- 密碼學 - 密碼學與密碼分析
- 密碼學 - 經典與量子
- 密碼學與隱寫術
- 密碼學與加密
- 密碼學與網路安全
- 密碼學 - 流密碼與分組密碼
- 密碼學 - AES 與 DES 密碼
- 密碼學 - 對稱與非對稱
- 密碼學有用資源
- 密碼學 - 快速指南
- 密碼學 - 討論
密碼學中的一次性密碼 (OTP) 演算法
由於網路安全威脅數量的增加,增強線上應用程式的安全性變得至關重要。您必須確保使用者帳戶的安全。
如今,許多線上 Web 應用程式需要使用者為其帳戶新增額外的安全層。他們透過啟用雙因素身份驗證來滿足此需求。實現雙因素身份驗證有多種選擇,其中之一是 TOTP(基於時間的一次性密碼)。
在本章中,我們將瞭解它是什麼以及如何以及為什麼要使用它。但首先,讓我們定義雙因素身份驗證。
雙因素身份驗證
因此,我們可以說雙因素身份驗證,通常稱為多因素身份驗證,為使用者帳戶提供了額外的安全層。這意味著在啟用雙因素身份驗證後,使用者仍需要完成一個步驟才能成功登入。例如,以下是訪問沒有一次性密碼和有的一次性密碼的帳戶的標準程式 -
因此,登入過程需要額外的步驟。因為駭客在不知道常規密碼和一次性密碼的情況下無法訪問使用者帳戶,所以我們可以說這種技術更安全。
現在有兩種流行的方法來獲取一次性密碼 -
- 基於簡訊的 - 使用此方法,每次使用者登入時,都會向用戶的註冊電話號碼傳送包含一次性密碼的簡訊。
- 基於 TOTP 的 - 此方法需要使用者使用特定的智慧手機應用程式掃描 QR 影像以開啟雙因素身份驗證。然後,該程式會持續生成使用者的一次性密碼。
基於簡訊的方法無需解釋。雖然它很簡單,但也有一些缺點,例如每次您想要登入時都必須等待簡訊以及安全問題。基於 TOTP 的方法相對於基於簡訊的方法的優勢使其越來越受歡迎。現在我們將分析基於 TOTP 的方法的操作。
TOTP(基於時間的一次性密碼)如何工作?
基於時間的一次性密碼 (TOTP) 方法透過生成在一定秒數間隔內(通常為 30 秒或更少)過期的臨時密碼來工作。它透過允許使用者輸入靜態密碼(他們知道的內容)和裝置生成的臨時密碼來提高身份驗證安全性。基本上,基於 TOTP 的方法的工作原理如下 -
- 初始化: - 使用者和服務提供商(網站或應用程式)在初始步驟中選擇一個共享金鑰。伺服器和使用者的裝置都維護此金鑰的安全性。
- 基於時間生成
- 要建立 TOTP,當前時間用作唯一性的來源。
- TOTP 技術使用共享金鑰和當前時間建立一個一次性密碼。
- 為了確保使用者裝置和伺服器之間的同步,時間通常被劃分為預定義的間隔,例如 30 秒或 1 分鐘的增量。
- 密碼顯示
- 生成的 TOTP 使用可信賴的裝置(智慧手機應用程式或硬體令牌)傳送給使用者。
- 使用者在身份驗證過程中輸入 TOTP 和其靜態密碼。
- 驗證
- 服務提供商獨立生成 TOTP,並使用已儲存的共享金鑰將其與使用者提供的 TOTP 進行驗證。
- 如果靜態密碼和兩個 TOTP 值都匹配,則使用者獲得訪問許可權。
- TOTP 最多有 30 秒的有效期,之後它會過期並需要重新整理。
- 持續身份驗證
- 每次嘗試登入時,都會為每個身份驗證會話提供一個新的 TOTP。
- 由於 TOTP 是基於時間的並且即使攻擊者攔截了先前的身份驗證嘗試,它也會頻繁更改,因此它對將來的嘗試沒有任何影響。
- 安全措施
- 透過向身份驗證過程新增第二個因素(使用者擁有的東西),TOTP 透過使其不易受到各種威脅(如重放攻擊和網路釣魚嘗試)的影響來提高安全性。
- 由於 TOTP 的生命週期很短,因此攻擊者攔截和操縱它們的機會視窗較小。
- 共享金鑰允許使用者生成有效的 TOTP,但前提是他們擁有相關裝置並知道靜態密碼。
TOTP 的安全性
與密碼不同,由於 TOTP 程式碼是一次性的,因此被洩露的憑據具有有限的生存期。當用戶需要將其 TOTP 程式碼輸入身份驗證頁面時,網路釣魚嘗試的可能性更大。由於 TOTP 程式碼具有有限的有效時間,因此攻擊者必須快速代理憑據。
TOTP 憑據基於客戶端和伺服器都瞭解的共享金鑰,這提供了更多可以檢索金鑰的位置。如果攻擊者知道此共享金鑰,他們將能夠生成新的有效 TOTP 程式碼。如果攻擊者能夠訪問大型身份驗證資料庫,這將變得尤其危險。
OTP 演算法的實現
現在,我們將藉助 Python、Java 等不同的程式語言來實現一次性密碼演算法。因此,讓我們檢視以下程式以更好地理解此演算法。
使用 Python 的 OTP
在本節中,我們將使用 Python 的 `secrets` 模組來實現 OTP。該模組提供了一些函式,用於生成密碼學意義上的強隨機數,適用於管理密碼、帳戶身份驗證和安全令牌等資料。它也是 Python 標準庫的一部分,在 Python 3.6 中引入。
這段程式碼展示了一個基本的 OTP 身份驗證過程,包括 OTP 生成和驗證。透過使用 Python 的 `secrets` 模組,我們將確保生成安全且不可預測的 OTP,以增強身份驗證系統的安全性。
因此,使用 `secrets` 模組實現 OTP 的 Python 程式碼如下所示:
import secrets
# Function to generate a random secret key
def generate_random_key():
return secrets.token_hex(16) # 16 bytes (32 hex characters)
# Function to generate a One Time Password (OTP) using the secret key
def generate_otp(secret_key, length=6):
# Define the characters allowed in the OTP
allowed_characters = "0123456789"
# Generate a random OTP using the secret key and allowed characters
otp = ''.join(secrets.choice(allowed_characters) for _ in range(length))
return otp
# Generate a random secret key (this should be kept secure)
secret_key = generate_random_key()
# Simulate sending the OTP to the user
otp = generate_otp(secret_key)
print("Generated OTP:", otp)
# Simulate user input for OTP verification
user_input = input("Please enter the received OTP: ")
# Verify the OTP entered by the user
if user_input == otp:
print("OTP verification successful. Access granted!")
else:
print("OTP verification failed. Access denied!")
輸出
執行上述程式後,我們將得到以下輸出。輸入正確的 OTP 程式碼將顯示訊息“訪問已授權!”,如果 OTP 錯誤,則顯示“訪問被拒絕”。
使用 Java 實現 OTP
在此 Java 程式碼中,我們將使用 `java.security.SecureRandom` 類,它是 Java 標準庫的一部分,並提供了一個密碼學意義上的強隨機數生成器 (RNG)。`SecureRandom` 類用於生成密碼學安全的隨機數。OTP 透過使用 `SecureRandom` 從允許的字元集中(0 到 9)隨機選擇字元來建立。生成的 OTP 將顯示給使用者。系統將提示使用者輸入收到的 OTP。輸入的 OTP 將與生成的 OTP 進行比較以驗證其正確性。如果輸入的 OTP 與生成的 OTP 匹配,則授予訪問許可權;否則,拒絕訪問。
因此,使用 Java 的實現如下所示:
import java.security.SecureRandom;
// Driver Class
public class OTPGenerator {
// Function to generate a random secret key
public static String generateSecretKey() {
SecureRandom secureRandom = new SecureRandom();
byte[] bytes = new byte[16];
secureRandom.nextBytes(bytes);
StringBuilder secretKey = new StringBuilder();
for (byte b : bytes) {
secretKey.append(String.format("%02x", b));
}
return secretKey.toString();
}
// Function to generate a One Time Password (OTP) using
// the secret key
public static String generateOTP(String secretKey, int length) {
String allowedCharacters = "0123456789";
StringBuilder otp = new StringBuilder();
SecureRandom secureRandom = new SecureRandom();
for (int i = 0; i < length; i++) {
int randomIndex = secureRandom.nextInt(allowedCharacters.length());
otp.append(allowedCharacters.charAt(randomIndex));
}
return otp.toString();
}
public static void main(String[] args) {
// Generate a random secret key
// (this should be kept secure)
String secretKey = generateSecretKey();
// Generate the OTP
int otpLength = 6;
String otp = generateOTP(secretKey, otpLength);
System.out.println("Generated OTP: " + otp);
// Simulating user input for OTP verification
java.util.Scanner scanner = new java.util.Scanner(System.in);
System.out.print("Please enter the received OTP: ");
String userInput = scanner.next();
// Verify the OTP entered by the user
if (userInput.equals(otp)) {
System.out.println("OTP verification successful. Access granted!");
} else {
System.out.println("OTP verification failed. Access denied!");
}
}
}
輸出