RSECTAB decryption (ABAP Secure Storage)
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 257
- Forks
- 72
- Avg merge
- 33m
- Merged PRs (30d)
- 6
Description
Hello everyone,
When changing default encryption key of ABAP Secure Storage entries (transaction SECSTORE), data is stored encrypted in hex format in table RSECTAB, field DATA.
The encryption key is stored in encrypted format in SSFS and can be decrypted with .KEY and .DAT files and the SSFS implementation in pysap.
However, to decrypt RSECTAB blob from DATA field usage of the decrypted key does not work properly.
I verified I had the right decrypted key as I stored a backup of it when generating it from the SECSTORE Wizard.
The issue is that the plaintext key is 29 bytes however pysap implementation with function rsectab below only accepts 24 bytes key length. I tried using the last 24 bytes or the first 24 bytes and some other random bytes permutation to only take a 24 bytes key as input without success.
Below is the pysap function I used for decryption which implements the RSECCipher class for the custom 3DES-EDE3 custom algorithm implementation of SAP.
I have also tried implementing a custom decryption algorithm following the algorithm details specified in this article SAP ABAP Secure Storage algorithm but without success. I see that decryption depends also on SID and Installation Number, so maybe I'm missing something ?
Any help would be appreciated, and many thanks in advance !
`def rsec_decrypt(blob, key):
"""Decrypts a blob of data using SAP's RSEC decryption algorithm. The algorithm is based on
the TripleDES.
The decryption method is used in SSFS but also as part of other encryption schemes (e.g. RSECTAB),
hence implemented in the crypto library instead of the particular layer.
:param blob: encrypted blob to decrypt
:type blob: bytes
:param key: key to use to decrypt
:type key: bytes
:return: decrypted blob
:rtype: bytes
:raise Exception: if decryption failed
"""
if len(key) != 24:
raise Exception("Wrong key length")
blob = [ord(i) for i in blob]
key = [ord(i) for i in key]
key1 = key[0:8]
key2 = key[8:16]
key3 = key[16:24]
cipher = RSECCipher()
round_1 = cipher.crypt(RSECCipher.MODE_DECODE, blob, key3, len(blob))
round_2 = cipher.crypt(RSECCipher.MODE_ENCODE, round_1, key2, len(round_1))
round_3 = cipher.crypt(RSECCipher.MODE_DECODE, round_2, key1, len(round_2))
return ''.join([chr(i) for i in round_3])`
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the rsec_decrypt function and RSECCipher implementation, then compare the SSFS and RSECTAB decryption paths described in the issue. Reproduce the failure with the 29-byte plaintext key and investigate the role of the SID and Installation Number; done means successfully decrypting the RSECTAB DATA blob with the correct key handling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cryptography, reverse-engineering, security
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 28/100