受入侵计算机中Ruby生成秘密随机数的高抗捕获熵源问询
Great question—when you're dealing with a compromised system where keyloggers or screen scrapers are active, Ruby's default Random.new.rand seed is way too predictable. Those time, PID, and sequence values are trivial for malware to snoop on, so you need to leverage entropy sources that are much harder to capture. Here are your best options:
Recommended Entropy Sources
System-Level Cryptographically Secure Random Generators
This is your first line of defense. Operating systems maintain entropy pools fed by low-level, hard-to-observe events: disk IO latency, network packet timing, hardware interrupt jitter, and more. Malware can't easily tap into all these inputs simultaneously.
In Ruby, use the built-inSecureRandommodule—it automatically uses/dev/urandom(Unix-like) or Windows'CryptGenRandomAPI under the hood. If you specifically need to seed aRandominstance, extract bytes fromSecureRandomand convert them to an integer:require 'securerandom' seed = SecureRandom.random_bytes(32).unpack1('Q*') # Convert 32 bytes to a 64-bit integer secure_rng = Random.new(seed)Hardware Random Number Generators (HRNGs)
Modern CPUs (Intel RDRAND/AMD RDSEED) have built-in hardware that generates true random numbers from physical noise. These values are generated directly in the CPU, making them nearly impossible for malware to intercept.
On Unix systems, you can read directly from/dev/random(note: this may block if the entropy pool is low) or use gems likerdrandto access the CPU instructions directly:# Using /dev/random (Unix-only) seed = File.open('/dev/random', 'rb') { |f| f.read(8).unpack1('Q*') } secure_rng = Random.new(seed)Process Memory Fragments
Uninitialized or dynamically allocated memory in your process often contains leftover data from previous operations or system-level activities. While some systems zero out memory on allocation, many don't—and this leftover data is unique to your process, hard for malware to read unless it has full process memory access (which is possible, but adds another layer of difficulty).
You can capture this entropy by allocating a large buffer and reading its content:require 'digest' # Capture entropy from uninitialized memory (example) random_buffer = (' ' * 4096).bytes seed = Digest::SHA256.hexdigest(random_buffer.to_s).to_i(16) secure_rng = Random.new(seed)Fine-Grained System State Metrics
Malware can easily grab the current time or PID, but it's much harder to capture the microscopic variations in system state: things like thread scheduling delays, disk IO wait times, or the exact timing of network socket operations.
On Unix systems, you can pull data from/procfilesystem entries like/proc/stator/proc/self/taskto get these granular metrics, then hash them into a seed:require 'digest' system_state = File.read('/proc/stat') + File.read('/proc/self/task') seed = Digest::SHA256.hexdigest(system_state).to_i(16) secure_rng = Random.new(seed)Non-Keyboard/Screen User Input (If Available)
If the system has input devices beyond the keyboard (mouse, touchpad, microphone), their raw input data or timing is hard for keyloggers/screen scrapers to capture. For example, mouse movement timing, touchpad pressure changes, or even background microphone noise can add high entropy.
You'll need platform-specific gems or system calls to access this data (e.g.,ruby-sdl2for input events), but combining this with other entropy sources creates a very robust seed.
Key Best Practices
- Combine Multiple Sources: Never rely on a single entropy source. Mix system-level randomness, memory fragments, and system state to ensure even if one source is compromised, others provide enough entropy.
- Prioritize
SecureRandom: It's battle-tested and cross-platform—use it directly instead of rolling your own seed whenever possible. - Avoid Blocking: Stick with
/dev/urandominstead of/dev/randomon Unix systems, as/dev/randomcan block when the entropy pool is low, which isn't ideal for scripts.
内容的提问来源于stack exchange,提问作者lunr

