hey madbury,
the answer to what the differences are between version 2 and version 3 Polkawallet algorithms can be seen within the source code of for instance the github repo linked above (polkadot-js or probably others too).
The main differences are these: NO SCRYPT !!! which should give you a HUGE performance advantage because scrypt is very slow (intentionally slow of course ! this is to make it difficult to brute-force or mask attack etc)
The main differences are here and these are probably also the 2 parts that you didn't find that easily (without my help, hehe):
1. no scrypt: https://github.com/polkadot-js/common/bl...ts#L27-L33
2. password to key conversion (just NUL-byte padding, hehe): https://github.com/polkadot-js/common/bl...ts#L20-L32
here is the python3 version, you could easily also convert the perl version etc... now that you have all the algorithm details:
polkawallet2.py:
of course you would need to adapt the "ENCODED" string (the most important data from the JSON file that is needed to verify a password). one could also think about adapting the script and taking 2 command line arguments, first could be the json wallet, second one could be the password... for convenience
hope this helps, thx
the answer to what the differences are between version 2 and version 3 Polkawallet algorithms can be seen within the source code of for instance the github repo linked above (polkadot-js or probably others too).
The main differences are these: NO SCRYPT !!! which should give you a HUGE performance advantage because scrypt is very slow (intentionally slow of course ! this is to make it difficult to brute-force or mask attack etc)
The main differences are here and these are probably also the 2 parts that you didn't find that easily (without my help, hehe):
1. no scrypt: https://github.com/polkadot-js/common/bl...ts#L27-L33
2. password to key conversion (just NUL-byte padding, hehe): https://github.com/polkadot-js/common/bl...ts#L20-L32
here is the python3 version, you could easily also convert the perl version etc... now that you have all the algorithm details:
polkawallet2.py:
Code:
#!/usr/bin/env python3
# Author: philsmd
# Date: April 2022
# License: public domain, credits go to philsmd and hashcat
# Note: NaCl uses XSalsa20 and Poly1305 for decrypting the data.
# there is *NO* key derivation for version 2 wallets ! i.e. the password is used AS-IS,
# but NULL-byte (\x00) padded to 32 bytes
# only tested with version 2 of a PolkaWallet test wallet
import binascii
import sys
from nacl.secret import SecretBox # install PyNaCl
#
# Examples
#
# const PAIR = '{"address":"5CczAE5AmGrZ93MeVhha3Ywam7j9dKB7cArnH7gtrXcMFJvu","encoded":"0xee8f236e2ac3217ce689692a4afc612220dc77fddaed0482f8f95136a7c3e034cccfbc495410a6e9b2439904974ed1d207abeca536ff6985ceb78edeeb3dc343e561c184c488101af8811d1331430b4ccf0e96ef507132e5132964e8564232e7100d973c5bee7b231dd0c8ad5273f3501515a422c8d7ed9d20a73c0ed17c98ee4588e54844bb73052dcad81f7a1094613d63c162fec7446c88b1fae70e","encoding":{"content":["pkcs8","sr25519"],"type":"xsalsa20-poly1305","version":"2"},"meta":{"genesisHash":"0xe143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e","name":"json v2","tags":[],"whenCreated":1595243159596}}';
# PASS2 = "versionTwo";
ENCODED = "0xee8f236e2ac3217ce689692a4afc612220dc77fddaed0482f8f95136a7c3e034cccfbc495410a6e9b2439904974ed1d207abeca536ff6985ceb78edeeb3dc343e561c184c488101af8811d1331430b4ccf0e96ef507132e5132964e8564232e7100d973c5bee7b231dd0c8ad5273f3501515a422c8d7ed9d20a73c0ed17c98ee4588e54844bb73052dcad81f7a1094613d63c162fec7446c88b1fae70e"
#
# Start
#
if len (sys.argv) < 2:
print ("ERROR: Please specify the dict file within the command line", file=sys.stderr)
sys.exit (1)
fp = None
try:
fp = open (sys.argv[1])
except:
print ("ERROR: Could not open dictionary file '%s'" % sys.argv[1], file=sys.stderr)
sys.exit (1)
if ENCODED[0:2] != "0x":
print ("ERROR: not a valid ENCODED string for version 2 wallets", file=sys.stderr)
sys.exit (1)
if len (ENCODED) < (2 + 24 + 32):
print ("ERROR: too short ENCODED string for version 2 wallets", file=sys.stderr)
sys.exit (1)
raw_data = binascii.unhexlify (ENCODED[2:])
nonce = raw_data[ 0:24]
encrypted = raw_data[24: ]
cracked = False
password = fp.readline ()
while password:
password = password.strip ()
key = (password + ("\x00" * 32)) [0:32] # pad with 32 \x00 bytes, take the first 32 bytes as key
key = key.encode () # python 3 shenanigans
box = SecretBox (key)
try:
box.decrypt (encrypted, nonce)
print ("Password found: '%s'" % password)
cracked = True
break
except:
password = fp.readline ()
# Cleanup:
fp.close ()
# Exit codes:
if cracked:
sys.exit (0)
else:
sys.exit (1)
of course you would need to adapt the "ENCODED" string (the most important data from the JSON file that is needed to verify a password). one could also think about adapting the script and taking 2 command line arguments, first could be the json wallet, second one could be the password... for convenience
hope this helps, thx