pysap.utils.crypto.rfc module¶
SAP RFC ab_scramble password obfuscation.
SAP’s RFC layer uses a symmetric XOR-based obfuscation scheme called ab_scramble to encode passwords on the wire in unencrypted (non-SNC) RFC/CPIC connections. The scheme is not a cryptographic hash — it is fully reversible given only the ciphertext.
Wire format¶
The password field is always:
[ 4-byte little-endian seed ][ obfuscated password bytes ]
The seed is chosen by the client at connection time.
Encoding variants¶
Two client-side encodings are observed in practice:
ASCII (classic SAPRFC / pyrfc): the plaintext password is encoded as ASCII bytes before obfuscation. The descrambled result is decoded with
"ascii".UTF-16LE (NetWeaver RFC SDK / npl_rfc / SAP JCo): the plaintext password is encoded as UTF-16LE before obfuscation. The descrambled result must be decoded with
"utf-16-le". Callers must passencoding="utf-16-le"explicitly.
References¶
Reverse-engineered from libsapnwrfc (SAP NWRFC SDK).
Confirmed against live PCAP captures of pyrfc and npl_rfc clients.
- pysap.utils.crypto.rfc.ab_descramble(raw, encoding='ascii')[source]¶
Descramble an SAP RFC ab_scramble password field.
- Parameters:
raw (bytes) – Full password field,
[4-byte LE seed][obfuscated bytes].encoding (str) – Character encoding of the obfuscated payload. Use
"ascii"(default) for classic SAPRFC / pyrfc clients. Use"utf-16-le"for NetWeaver RFC SDK (npl_rfc, JCo) clients.
- Returns:
Plaintext password.
- Return type:
str
- Raises:
ValueError – If raw is shorter than
_MIN_FIELD_SIZEbytes.UnicodeDecodeError – If the descrambled bytes cannot be decoded with the given encoding.
Example:
>>> from pysap.utils.crypto.rfc import ab_descramble >>> ab_descramble(bytes.fromhex("a3b7e05a3384be74606be2de")) 'secret'
- pysap.utils.crypto.rfc.ab_scramble(password, seed=None, encoding='ascii')[source]¶
Scramble a plaintext password using SAP’s ab_scramble algorithm.
- Parameters:
password (str) – Plaintext password to obfuscate. SAP enforces a maximum length of 40 characters.
seed (int or None) – 32-bit unsigned seed value. A cryptographically random seed is generated when seed is
None.encoding (str) – Character encoding to apply to password before obfuscation. Use
"ascii"(default) for classic clients or"utf-16-le"for NetWeaver RFC SDK clients.
- Returns:
Full password field,
[4-byte LE seed][obfuscated bytes].- Return type:
bytes
- Raises:
UnicodeEncodeError – If password cannot be encoded with encoding.
Example:
>>> from pysap.utils.crypto.rfc import ab_scramble, ab_descramble >>> raw = ab_scramble("secret", seed=0x12345678) >>> ab_descramble(raw) 'secret'