Last active
April 17, 2021 18:14
-
-
Save sh4dowb/4d39cc0f6a30f7df43e202d9ffb26e2c to your computer and use it in GitHub Desktop.
Decrypt Ruby's ActiveSupport::MessageEncryptor on Python 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import hashlib | |
import base64 | |
from Crypto import Random | |
from Crypto.Cipher import AES | |
import rubymarshal.reader | |
from pbkdf2 import PBKDF2 | |
SECRET = "asdasd" | |
ITERATIONS = 65536 | |
KEYLENGTH = 32 | |
saltdic = {} # dont generate key again if it exists | |
def decrypt_secret(encrypted): | |
global saltdic | |
salt = encrypted.split('.')[0] | |
parts = encrypted.split('.')[1].split(b"--") | |
if salt not in saltdic: | |
key = PBKDF2(SECRET, salt, ITERATIONS).read(KEYLENGTH) | |
saltdic[salt] = key | |
key = saltdic[salt] | |
ciphertext = base64.b64decode(parts[0]) | |
iv = base64.b64decode(parts[1]) | |
aes = AES.new(key, AES.MODE_GCM, iv) | |
decrypted = aes.decrypt(ciphertext) | |
data = rubymarshal.reader.loads(decrypted) | |
return data | |
ruby_encrypted_message = "" # "salt.base64message--base64salt--base64signature" | |
# we dont check for signature | |
print(decrypt_secret(ruby_encrypted_message)) # plaintext |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment