時鐘偏移通常不會讓現代密碼產生器輸出重複密碼,前提是它呼叫作業系統的密碼學安全亂數產生器(CSPRNG);真正會出問題的是把系統時間當成唯一種子的簡易實作。密碼產生器 若依賴系統提供的隨機數介面,時間回撥帶來的影響通常可以忽略。
早期或教學用途的程式常寫成 random.seed(time()),用當下時間戳當種子。只要兩次產生落在同一個時間單位,或是時鐘被回撥,種子就會相同,輸出整段相同的隨機序列,密碼自然重複。這類方法沒有額外熵源可依靠:虛擬機從快照還原、主機板 CMOS 電池耗盡導致開機時鐘重置,都會讓時間倒退並反覆使用同一顆種子。攻擊者只要掌握時間範圍,就有機會重現同樣的密碼。若只是日常要產生一組夠強的密碼,直接用 隨機密碼產生器 即可,不必自行處理種子問題。
random.seed(time())
CSPRNG 不會把單一時間戳當成種子。系統初始化時會綜合硬體中斷、磁碟與網路事件、使用者輸入等多種熵源填入熵池,時間只是其中一項輔助輸入;之後熵池持續吸收新熵並經內部狀態擴展,單一來源偏移不足以讓整體輸出變得可預測。因此即使系統時鐘偏移或回撥,亂數重複與可預測的風險仍大幅降低——這是「時間種子」與「多熵源」的根本差別。開發瀏覽器擴充功能(例如 密碼產生器chrome)時也一樣,應走 crypto.getRandomValues() 這類系統提供的介面。
crypto.getRandomValues()
比時鐘偏移更需要留意的是熵池本身不足。虛擬機若沒有 virtio-rng 等裝置,或 IoT 嵌入式裝置缺乏硬體亂數來源,開機初期可用的熵很少;此時就算時間正確,輸出仍可能重複或易於預測。這類環境建議確認系統是否具備有效的熵源補充機制,必要時延後密碼產生,或接入硬體安全晶片等外部熵源輔助。
實務上把握幾點:直接使用系統原生 CSPRNG 介面(Linux 的 getrandom、Windows 的 BCryptGenRandom、瀏覽器的 crypto.getRandomValues),不要自行用 time.time() 之類的值當種子;多實例並行產生密碼時,各自獨立呼叫系統亂數介面,避免共用可變狀態。一般使用者則選用基於系統 CSPRNG 的 密碼產生器 多組 工具即可,不必為時鐘偏移操心。
getrandom
BCryptGenRandom
crypto.getRandomValues
time.time()
這篇主要適合需要理解底層熵源與亂數生成機制的軟體開發者與系統維運人員,尤其是管理虛擬機、容器或嵌入式裝置的人。若你只是要一組可用的密碼,不適合自行實作亂數演算法,直接選用市面上評價良好的工具就好。局限在於:如果系統熵源本身不足,或工具沒有正確使用 CSPRNG,仍有重複風險,時鐘偏移只是整體熵池問題的一環。一般使用者只要選用主流平台的 亂數密碼產生器,日常場景下的時鐘偏移通常不需要擔心。