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.

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_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.

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'