Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I've written a code in php (as a service) to decrypt passwords sent over a protocol. The protocol demands the password to be "Mac then Encrypt"ed (MtE) using AES256, then encoded using base-64.

The message structure is as described in this comment on php.net.

base46encoded (iv + ecrypted(mac + password))

The process was easy using php

public static function getPassword($password, $key, $mac_algorithm = 'sha1',
                                       $enc_algorithm = MCRYPT_RIJNDAEL_256, $enc_mode = MCRYPT_MODE_CBC)
    {
        // truncating pre-shared key to 32 bytes.
        $key = substr($key, 0, 32);

        // decoding the message (being a password) from base64
        $password = base64_decode($password);

        // getting the iv size based on algorithm and encryption mode
        $iv_size = mcrypt_get_iv_size($enc_algorithm, $enc_mode);

        // extracting iv from message header (normally the first 32 byte) for decryption
        $iv_dec = substr($password, 0, $iv_size);

        // getting the encrypted message after the header (after the first 32 byte)
        $password = substr($password, $iv_size);

        // decrypting message using the pre-shared key and extracted iv
        $password = mcrypt_decrypt($enc_algorithm, $key, $password, $enc_mode, $iv_dec);

        // getting block size for hash algorithm in bytes (sha1 block size is 160 bit)
        $mac_block_size = ceil(static::getMacAlgoBlockSize($mac_algorithm)/8);

        // extracting the mac from the header of decrypted message
        $mac_dec = substr($password, 0, $mac_block_size);

        // extracting the valuable message
        $password = substr($password, $mac_block_size);

        // eliminate extra null terminators padded as the result of enc/decryption the following if and the next statement are check clauses for unpack function
        $password = unpack('Z*', $password);
        if (!isset($password[1]))
        {
            return false;
        }

        // obtaining the pure intended message (being the password) from the unpack result
        $password = $password[1];

        // regenerating the mac to control the authenticity and correctness of transmission
        $mac = hash_hmac($mac_algorithm, $password, $key, true);

        // see if transmitted mac (mac_dec) and the generated mac are the same and the data is valid
        if($mac_dec == $mac)
        {
            return $password;
        }
        else
        {
            return false;
        }
    }

Now the problem is, the application is developed around this protocol in iOS, and tried AESCrypt and CCCrypt, but the decryption results are different (gibberish).

We used standard CCHmac, Base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn and This SO answer for CCCrypt.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
243 views
Welcome To Ask or Share your Answers For Others

1 Answer

The mcrypt_generic_init function initializes the cipher by specifying both the key and the IV. The length of the key determines whether we're doing 128-bit, 192-bit, or 256-bit encryption.

So use MCRYPT_RIJNDAEL_128 with a 256-bit (32-byte) key to be compatible with AES256.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...