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 pass encoding="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.

Args:

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:

str: Plaintext password.

Raises:

ValueError: If raw is shorter than _MIN_FIELD_SIZE bytes. 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.

Args:

password (str): Plaintext password to obfuscate (SAP enforces ≤ 40 chars). seed (int | None): 32-bit unsigned seed value. A cryptographically

random seed is generated when seed is None (default).

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:

bytes: Full password field — [4-byte LE seed][obfuscated 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'