重构RSA密码系统:如何利用已有变量实现PKCS1 OAEP填充?
Great question—let's break this down clearly. First, we'll verify if you have all the required pieces, then walk through a practical implementation using your existing variables.
Are Your Variables Complete?
Almost, but you're missing a few critical components required for OAEP (per RFC 8017):
- Cryptographically secure random number generator: OAEP relies on a random seed
rto ensure semantic security—you can't use non-secure randomness here. - MGF1 (Mask Generation Function) implementation: This is a core part of OAEP, used to generate the masks needed for padding.
- A working SHA-1 hash function instance: Your existing
hashvariable is the hex digest of an empty string (the label hashH(L)whereLis empty), but you need the actual hash function to compute other digests for MGF1.
Also, note that your hash_length is 40 (the length of the hex string), but the actual byte length of a SHA-1 digest is 20—we'll need to convert that hex string back to bytes for the padding process.
Step-by-Step OAEP Padding Implementation
Let's use your existing variables and fill in the gaps with Python code (since it's readable for learning purposes). We'll follow the official OAEP specification closely.
First, Define Helper Functions &补充 Components
import hashlib import secrets # For cryptographically secure randomness def mgf1(seed, mask_len, hash_func=hashlib.sha1): """Implementation of MGF1 as defined in RFC 8017.""" mask = b"" counter = 0 while len(mask) < mask_len: # Convert counter to 4-byte big-endian value counter_bytes = counter.to_bytes(4, byteorder='big') # Hash the seed + counter bytes hash_output = hash_func(seed + counter_bytes).digest() mask += hash_output counter += 1 # Truncate to the desired mask length return mask[:mask_len]
Now, Execute the Padding Process
We'll use your exact variables and walk through each step:
# Your existing variables message = "Hello World" message_length = len(message) # 11 empty_label_hash_hex = "da39a3ee5e6b4b0d3255bfef95601890afd80709" mod_size = (66707621741034658424514206418677753964865266688022969048429208771289785288847727334295743540860932900769628607474618294659295004562698532947535801821428015940719336654123007538255459184765551631213180128939808032261346408111382837800099426844454970753309552867519518744723276317986718923680385211621637413963).bit_length() # 1023 mod_size_bytes = -(-mod_size // 8) # 128 bytes (correct, since 1023 bits rounds up to 128 bytes) #补充 critical values hash_func = hashlib.sha1 hash_byte_len = hash_func().digest_size # 20 bytes (SHA-1's output length) empty_label_hash = bytes.fromhex(empty_label_hash_hex) # Convert hex to bytes # 1. Validate message length (OAEP hard requirement) max_allowed_message_len = mod_size_bytes - 2 * hash_byte_len - 2 if message_length > max_allowed_message_len: raise ValueError(f"Message too long! Maximum allowed length is {max_allowed_message_len} characters.") # 2. Build the DB (Data Block) message_bytes = message.encode('utf-8') # Convert string to bytes ps_len = mod_size_bytes - len(message_bytes) - 2 * hash_byte_len - 2 ps = b"\x00" * ps_len # Padding string (all null bytes) db = empty_label_hash + ps + b"\x01" + message_bytes # DB = L_hash || PS || 0x01 || M # 3. Generate random seed r (must be cryptographically secure!) r = secrets.token_bytes(hash_byte_len) # 4. Generate mask for DB db_mask = mgf1(r, mod_size_bytes - hash_byte_len - 1) # 5. Compute masked DB masked_db = bytes([b ^ m for b, m in zip(db, db_mask)]) # 6. Generate mask for the seed seed_mask = mgf1(masked_db, hash_byte_len) # 7. Compute masked seed masked_seed = bytes([b ^ m for b, m in zip(r, seed_mask)]) # 8. Final padded message ready for RSA encryption padded_message = b"\x00" + masked_seed + masked_db # Verify the padded length matches the modulus byte size assert len(padded_message) == mod_size_bytes, "Padded message length mismatch!" print("OAEP padding completed successfully.")
Key Notes to Remember
- Randomness is non-negotiable: Always use a cryptographically secure random number generator (like
secretsin Python) forr—usingrandommodule will break the security of OAEP. - Hash consistency: Ensure you use the same hash function (SHA-1 here) for all steps (label hash, MGF1). If you switch to a stronger hash like SHA-256, adjust all hash length values accordingly.
- Message length limits: OAEP restricts the maximum message length to
k - 2h - 2(wherekis modulus byte length,his hash byte length). Your 11-byte message is well within the 86-byte limit for your 128-byte modulus.
内容的提问来源于stack exchange,提问作者ShellRox

