Posts: 1
Threads: 1
Joined: Feb 2024
02-01-2024, 07:46 PM
(This post was last modified: 02-01-2024, 07:57 PM by Qwarkz.)
Hey!
I use the Phantom wallet extension (a Solana crypto wallet) but it got suddently corrupted and now when i try to login using my password, which is written since a long time on a text file on my computer, i have this error message "Something went wrong, please try again later".
I assume that the extension got corrupted (maybe after some clearing cache, idk) and the best and quickest way to recover the wallet is using my seed phrase but since i wasn't expecting that at all, i still haven't backed up it and i need to find an other solution.
After some research, i found from a reliable source that Phantom wallet store the seed phrase locally (i use Windows 10) on the extension files (a .ldb file) and is encrypted by the wallet password (that i have).
I found my encrypted seed phrase, it looks like this :
{"encryptedKey"{"digest":"sha256","encrypted":"wFCwaUXv2nCNS1vBcuZiXnhS1hNK2e5ZerPTWz1Nst37x64WQBmMS1QWuetdp3X4P","iterations"10000"kdf":"pbkdf2","nonce":"2AeSHJN3yAviUqmg3AGqRjdZEAjX7mAq4","salt":"q9FJnyK8eaQPEz7XsNgUT"},"version":1}
(PS : it is an encrypted seed phrase from a new Phantom wallet with no funds on it)
After some other research, i heard about the "Metamask vault decryptor", which is a tool that can decrypt those type of encrypted data by using the wallet password but unfortunately it works only with Metamask wallet.
It's for this i'm here now to ask if there is a gigabrain that know a tool or a script to decrypt this gibberish? The wallet contain $2k, which is precious money for me. I promise a $200 reward for the person who helped me to decrypt this.
(PS : if that can help, i assume that the encryption and decryption code for Phantom wallet is quite similar to the code that you can find on this article : https://medium.com/@alevymyers/recoverin...a59e61ae08)
If you need any extra infos, feel free to ask.
Nice greetings!
Posts: 2
Threads: 0
Joined: Apr 2024
Posts: 165
Threads: 2
Joined: Apr 2021
(02-01-2024, 07:46 PM)Qwarkz Wrote: {"encryptedKey"{"digest":"sha256","encrypted":"wFCwaUXv2nCNS1vBcuZiXnhS1hNK2e5ZerPTWz1Nst37x64WQBmMS1QWuetdp3X4P","iterations"10000"kdf":"pbkdf2","nonce":"2AeSHJN3yAviUqmg3AGqRjdZEAjX7mAq4","salt":"q9FJnyK8eaQPEz7XsNgUT"},"version":1}
(PS : it is an encrypted seed phrase from a new Phantom wallet with no funds on it)
I may take a look at this. Do you remember the password you used for this example wallet? ^
Posts: 165
Threads: 2
Joined: Apr 2021
Research dump for whoever picks this up (Potentially me)
It appears to be PBKDF2_SHA256 KDF of the password then using xsalsa20-poly1305 for the encryption/decryption using tweetnacl's "secretbox" function
https://github.com/project-serum/spl-tok...#L124-L130
Will likely be quite a large effort to implement this, as xsalsa20-poly1305 hasn't been implemented before and the Phantom codebase is a mess
Posts: 2
Threads: 0
Joined: Apr 2024
(04-04-2024, 05:58 AM)penguinkeeper Wrote: Research dump for whoever picks this up (Potentially me)
It appears to be PBKDF2_SHA256 KDF of the password then using xsalsa20-poly1305 for the encryption/decryption using tweetnacl's "secretbox" function
https://github.com/project-serum/spl-tok...#L124-L130
Will likely be quite a large effort to implement this, as xsalsa20-poly1305 hasn't been implemented before and the Phantom codebase is a mess
Thanks for the reply penguinkeeper. Given the encrypted seed phrase, is there an easy way to find the public key? That would help me confirm how much funds are on the wallet so I can offer a bounty as well that could incentivize the effort needed to implement this. Thank you, and I hope you keep looking into this.
Posts: 165
Threads: 2
Joined: Apr 2021
No, it'd have to be cracked first so the private/public key can be derived from the phrase. What was the password to the above example you provided?
Posts: 5
Threads: 0
Joined: Apr 2024
04-11-2024, 01:13 PM
(This post was last modified: 04-11-2024, 01:17 PM by bingussssssss.)
hi, I just solved this --- i don't check this forum, but feel free to add me on discord if you don't hear back..
here's how you can fix it.
the first script will give you a 128 byte string, which you can then convert into a 12 word mnemonic with the 2nd script and import into your wallet.
tips appreciated: F8UghnajaBdfj5cNBSY8ztGg4EfnaY6XJayBPZiJTpm9 (SOL) -- this 100% works, ping me on discord or here if you have trouble.
discord user: o7_
import base58
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
from nacl.secret import SecretBox
from nacl.exceptions import CryptoError
# Encrypted data and parameters (assuming all are base58 encoded)
data = {
"encrypted": "",
"nonce": "",
"salt": "",
"iterations": 10000,
}
password = '' # Replace with your actual password
# Decode from Base58
salt = base58.b58decode(data['salt'])
nonce = base58.b58decode(data['nonce'])
encrypted_data = base58.b58decode(data['encrypted'])
# Derive the key using PBKDF2 with SHA-256
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=data['iterations'],
backend=default_backend()
)
key = kdf.derive(password.encode())
# Decrypt the data using PyNaCl's SecretBox
box = SecretBox(key)
try:
decrypted = box.decrypt(encrypted_data, nonce)
# Instead of attempting to decode as UTF-8, print the raw bytes or their hex representation
print("Decrypted data (hex):", decrypted.hex())
except CryptoError as e:
print(f"Decryption failed: {e}")
##################SECOND SCRIPT BELOW##############################
##################SECOND SCRIPT BELOW##############################
##################SECOND SCRIPT BELOW##############################
##################SECOND SCRIPT BELOW##############################
##################SECOND SCRIPT BELOW##############################
##################SECOND SCRIPT BELOW##############################
##################SECOND SCRIPT BELOW##############################
##################SECOND SCRIPT BELOW##############################
from mnemonic import Mnemonic
import binascii
# Decrypted data in hex
decrypted_hex = 'your_128_byte_string'
# Convert hex to bytes
entropy_bytes = binascii.unhexlify(decrypted_hex)
# Generate mnemonic from the entropy bytes
mnemo = Mnemonic("english")
mnemonic = mnemo.to_mnemonic(entropy_bytes)
print("Mnemonic:", mnemonic)
Posts: 5
Threads: 0
Joined: Apr 2024
04-11-2024, 01:33 PM
(This post was last modified: 04-11-2024, 01:34 PM by bingussssssss.)
(04-04-2024, 05:58 AM)penguinkeeper Wrote: Research dump for whoever picks this up (Potentially me)
It appears to be PBKDF2_SHA256 KDF of the password then using xsalsa20-poly1305 for the encryption/decryption using tweetnacl's "secretbox" function
https://github.com/project-serum/spl-tok...#L124-L130
Will likely be quite a large effort to implement this, as xsalsa20-poly1305 hasn't been implemented before and the Phantom codebase is a mess
(04-07-2024, 08:25 PM)tachsahtac Wrote: (04-04-2024, 05:58 AM)penguinkeeper Wrote: Research dump for whoever picks this up (Potentially me)
It appears to be PBKDF2_SHA256 KDF of the password then using xsalsa20-poly1305 for the encryption/decryption using tweetnacl's "secretbox" function
https://github.com/project-serum/spl-tok...#L124-L130
Will likely be quite a large effort to implement this, as xsalsa20-poly1305 hasn't been implemented before and the Phantom codebase is a mess
Thanks for the reply penguinkeeper. Given the encrypted seed phrase, is there an easy way to find the public key? That would help me confirm how much funds are on the wallet so I can offer a bounty as well that could incentivize the effort needed to implement this. Thank you, and I hope you keep looking into this.
(04-08-2024, 05:04 AM)penguinkeeper Wrote: No, it'd have to be cracked first so the private/public key can be derived from the phrase. What was the password to the above example you provided?
check my previous reply --- thanks penguin for the xsalsa callout -- it helped tremendously
Posts: 5
Threads: 0
Joined: Apr 2024
04-12-2024, 11:39 AM
(This post was last modified: 04-12-2024, 11:44 AM by bingussssssss.)
import base58
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
from nacl.secret import SecretBox
from nacl.exceptions import CryptoError
data = {
"encrypted": "", # Replace with your actual encrypted data
"nonce": "",# Replace with your actual nonce
"salt": "", # Replace with your actual salt password
"iterations": 10000,
}
password = '' # Replace with your actual password
# Decode from Base58
salt = base58.b58decode(data['salt'])
nonce = base58.b58decode(data['nonce'])
encrypted_data = base58.b58decode(data['encrypted'])
# Derive the key using PBKDF2 with SHA-256
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=data['iterations'],
backend=default_backend()
)
key = kdf.derive(password.encode())
# Decrypt the data using PyNaCl's SecretBox
box = SecretBox(key)
try:
decrypted = box.decrypt(encrypted_data, nonce) # Your private key in hex string format
except CryptoError as e:
print(f"Decryption failed: {e}")
# Convert hex to bytes
entropy_bytes = binascii.unhexlify(decrypted.hex()))
# Generate mnemonic from the entropy bytes
mnemo = Mnemonic("english")
mnemonic = mnemo.to_mnemonic(entropy_bytes)
print("Mnemonic:", mnemonic)
Made it just one script which will print your Mnemonic -- Remember though, even the decrypted hex string is sensitive.
Posts: 165
Threads: 2
Joined: Apr 2021
(04-19-2024, 08:42 AM)Markelov69 Wrote: Thank you for your response, penguinkeeper. Is there a straightforward method for locating the public key with the encrypted seed phrase? This would assist me in verifying the amount of funds in the wallet, enabling me to offer a bounty that could motivate the effort required to implement this. Your continued exploration of this matter is appreciated. I already addressed this previously - it isn't possible. Also, is the solution above not fit for your purpose?
|