如何从pyasn1对象恢复底层数据并提取原编码T61Strings?
Absolutely, you can solve this problem cleanly with pyasn1—let’s break down exactly how to grab those raw, unmodified T61String (and similar type) substrate bytes without relying on re-encoding.
The Key: Retain Substrate Data During Decoding
By default, pyasn1’s BER decoder discards the original raw bytes once it parses the ASN.1 structure. But you can override this by enabling the withSubstrate=True flag when decoding. This tells the decoder to attach the original BER-encoded substrate (including tag, length, and content bytes) to each parsed ASN.1 object, which you can then retrieve with the get_substrate() method.
Step-by-Step Implementation
Decode with Substrate Preservation
First, decode your raw ASN.1 byte stream while keeping the original substrate data:from pyasn1.codec.ber import decoder from pyasn1.type import univ, char # Replace with your actual raw ASN.1 BER bytes raw_asn1_bytes = b"...your nested ASN.1 bytes here..." # Decode with substrate retention enabled decoded_object, remaining_bytes = decoder.decode(raw_asn1_bytes, withSubstrate=True)Recursively Traverse and Extract T61String Substrates
Write a recursive function to walk the nested ASN.1 structure, identify T61String (and related) objects, and pull their raw substrate bytes:def extract_raw_t61_strings(asn1_object): raw_t61_data = [] # Check if current object is a T61String (add similar types here if needed) if isinstance(asn1_object, char.T61String): raw_t61_data.append(asn1_object.get_substrate()) # Recurse into sequence/set types (common nested structures) elif isinstance(asn1_object, (univ.Sequence, univ.Set, univ.SequenceOf, univ.SetOf)): for component in asn1_object: raw_t61_data.extend(extract_raw_t61_strings(component)) # Handle choice types (another common nested pattern) elif hasattr(asn1_object, "getComponent"): try: active_component = asn1_object.getComponent() raw_t61_data.extend(extract_raw_t61_strings(active_component)) except Exception: pass return raw_t61_data # Get all raw T61String substrate bytes from your decoded structure all_raw_t61 = extract_raw_t61_strings(decoded_object)
Why This Works
- The
get_substrate()method returns the exact bytes that were parsed from the original ASN.1 stream for that T61String—no re-encoding, no modifications. This is perfect for your encryption logic that requires strict byte matching. - You can easily extend the
isinstancecheck to include other similar character types (likechar.UniversalStringorchar.PrintableString) if you need to capture those too.
Quick Note
Make sure you’re using a recent version of pyasn1—older releases may have limited support for withSubstrate. Update it with:
pip install --upgrade pyasn1
内容的提问来源于stack exchange,提问作者PythonAteMyHamster

