Hi, I am trying to encode a string using Rijndael-128 using a C application
that I wrote, based on the BSD crypt/rijndael libarary and decode it in PHP
using mcrypt_decrypt. Each part of the program works separately (I can
encrypt with the c app, and decrypt with it, and I can encrypt with
mcrypt_encrypt and decrypt with the mcrypt_decrypt method).

Both use CBC mode, and I have the C process generate a random IV that is
also sent to the PHP process. I have verified that the IV is correctly
picked off of the stream, and stored.

Additionally, the key is stored in hex, and converted to binary for both
processes. The output strings are converted to Base64.

Both applications are currently running on the same system.

Demo app is at http://www.bbroerman.net/aestest.php

The PHP code for the decode is:

// Base64 decode the input (turn into binary)
$decoded = base64_decode($decrypt);

// Get the size of the IV
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);

// Split the incoming message into the original IV and the cryptext
$iv = substr($decoded,0,$iv_size);
$string = substr($decoded,$iv_size);

// Decode the cryptext.
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, pack('H*',$key), $string,
MCRYPT_MODE_CBC, $iv);


and the C code for encrypt is (unnecessary helper methods removed):

// Convert key to binary from a hex string.
char* binkey = NULL;
int tmpkeylen;
hex2dec( key, &binkey, &tmpkeylen );

// Make sure the message is padded to the correct block length.
unsigned int msglen = strlen(messageSrc);
char* paddedMsg = NULL;
if( msglen % 16 != 0 )
{
    int padding = 16 - msglen % 16;
    paddedMsg = malloc( msglen + padding + 1 );
    memset( paddedMsg, 0, msglen + padding + 1 );
    strncpy( paddedMsg, messageSrc, msglen );
    msglen = msglen + padding;
}
else
{
    paddedMsg = malloc( msglen+1 );
    memset( paddedMsg, 0, msglen+1 );
    strncpy( paddedMsg, messageSrc, msglen );
}

// Build a random IV block.
int idx;
char iv[RIJNDAEL_MAX_IV_SIZE];
for(idx = 0; idx < RIJNDAEL_MAX_IV_SIZE; ++idx)
{
    iv[idx] = get_random() & 0xFF;
}

// Initialize the cypher instance, in CBC mode.
int retCd = rijndael_cipherInit(&ci, MODE_CBC, iv);

// Make the key.
rijndael_makeKey(&ki, DIR_ENCRYPT, 128, binkey);

// Encrypt the message.
out = (char*)malloc(msglen*8);
retCd = rijndael_blockEncrypt(&ci, &ki, paddedMsg, msglen * 8, out);

// Now, take the IV and the output cryptext, and compose the output message.
char* fullmsgbuff = malloc( RIJNDAEL_MAX_IV_SIZE + msglen + 1);

for( idx = 0; idx < RIJNDAEL_MAX_IV_SIZE; ++idx )
fullmsgbuff[idx] = iv[idx];

for(; idx < RIJNDAEL_MAX_IV_SIZE + msglen; ++idx )
fullmsgbuff[idx] = out[idx - RIJNDAEL_MAX_IV_SIZE];

// Base64 encode the output.
char* buffout;
base64encode(fullmsgbuff, msglen + RIJNDAEL_MAX_IV_SIZE, &buffout);

// and print it all out.
fprintf(stdout, "%s", buffout);


-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to