Author

Topic: the goxsh script is zero-padding the secret and then encrypting in ECB mode (Read 997 times)

full member
Activity: 154
Merit: 100
hello!

I am not a crypto-guru, so I might be wrong but this seems highly suspicious to me:


      password = password[0:32]
      aes = AES.new(password, AES.MODE_ECB)
      secret = str.zfill(secret, 128)
      secret = aes.encrypt(secret)


It turns out that before zero padding the length of secret is 88 bytes and after it is 128 bytes, so there is more than one complete block (key length = 32 bytes) of known plaintext and because of ECB mode all other 32 byte blocks will be encoded with the very same key! Isn't this danegrous? Shouldn't it be padded with random bytes instead and also the ECB mode be completely avoided?
I'm no crypto guru either, but here is a simple attack:

Code:
# passwords is a large list of common passwords
passwords = ['querty', 'password', ... ]

# map of encrypted null block (i.e. result of encrypting zero) => password
zeroCiphers = {}

# fill the zeroCiphers
for password in passwords:
    aes = AES.new(password, AES.MODE_ECB)
    zeroCiphers[aes.encrypt(0)] = password


def decrypt(ciphertext):
    # get the last block (we're hoping it's from encrypting the zero padding)
    lastBlock = cipertext[-16:]

    # look up this encrypted zero byte in our table to get the password
    password = zeroCiphers[lastBlock]

    if(password !== null):
        # BINGO!
        aes = AES.new(password, AES.MODE_ECB)
        return aes.decrypt(ciphertext)
    else:
        return '';

Quick fix is to change to Cipher Block Chaining, so that the cipher changes every block, you don't know block were originally zero padding.


Please send a share of any stolen bitcoins to the address in my sig Wink
hero member
Activity: 938
Merit: 500
https://youengine.io/
hello!

I am not a crypto-guru, so I might be wrong but this seems highly suspicious to me:


      password = password[0:32]
      aes = AES.new(password, AES.MODE_ECB)
      secret = str.zfill(secret, 128)
      secret = aes.encrypt(secret)


It turns out that before zero padding the length of secret is 88 bytes and after it is 128 bytes, so there is more than one complete block (key length = 32 bytes) of known plaintext and because of ECB mode all other 32 byte blocks will be encoded with the very same key! Isn't this danegrous? Shouldn't it be padded with random bytes instead and also the ECB mode be completely avoided?
Jump to: