I have a function in PHP that encrypts and decrypts strings:
function encrypt_decrypt($action, $string)
{
$output = false;
$key = \'mykeyhereblah\';
$i
Ok there are a few things to point out here... First of all MD5 is not going to give you enough entropy to consider that key secure. While the IV can be even public it should anyway be random and thus, md5 is not working there either. Mind that having a fixed IV is more or less not having it at all.
If you want to really use a passphrase to generate your encryption key the best way to do it is to use PBKDF2
Now to the code:
This is the code I'm currently using in one of my project
- (NSData *)AES256EncryptWithKey:(NSString *)key andIV:(const void*)iv
{
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
bzero( keyPtr, sizeof( keyPtr ) ); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof( keyPtr ) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc( bufferSize );
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt( kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
iv /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted );
if( cryptStatus == kCCSuccess )
{
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free( buffer ); //free the buffer
return nil;
}
- (NSData *)AES256DecryptWithKey:(NSString *)key andIV:(const void*)iv
{
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
bzero( keyPtr, sizeof( keyPtr ) ); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof( keyPtr ) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc( bufferSize );
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt( kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
iv /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesDecrypted );
if( cryptStatus == kCCSuccess )
{
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free( buffer ); //free the buffer
return nil;
}
The above code was borrowed from this SO's answer
Now following is part of the code I used in one of my projects. Mind that this is functions are part of an object and I didn't post all the code, just the relevant.
/**
* Pads the data using PKCS7 padding scheme, as described in RFC 5652.
*
* We do not want to rely on Mcrypt's zero-padding, because it differs from
* OpenSSL's PKCS7 padding.
*
* Note: $data is passed by reference.
*
* @param string &$data
*/
static public function pkcs7Pad(&$data)
{
$blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$padding = $blockSize - (strlen($data) % $blockSize);
$data .= str_repeat(chr($padding), $padding);
}
/**
* Removes the (PKCS7) padding bytes from $data.
*
* Note: $data is passed by reference.
*
* @param string &$data
*/
static public function pkcs7Strip(&$data)
{
$paddingByte = substr($data, -1);
$paddingLen = ord($paddingByte);
$dataLen = strlen($data) - $paddingLen;
// Simple sanity check to make sure we have correct padding bytes. If padding
// is not correct, we simply set $data to false. At this point, there
// should be no need to worry about leaking side-channels.
if (!isset($data[15]) || $paddingLen < 1 || $paddingLen > mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC) )
{
//$data = false;
}
else if (substr($data, $dataLen) === str_repeat($paddingByte, $paddingLen))
{
// Padding is correct, strip it off.
$data = substr($data, 0, $dataLen);
}
else
{
//$data = false;
}
}
public static function encrypt($dataString, $aesCipherKey, $iv = null, $returnBase64Encoded = false){
// ensure source file exist
if (!$dataString || empty($dataString))
return null;
try{
// ===========
// Ciphering
$ciphered_data = null;
//Make sure padding is pkcs7 based
self::pkcs7Pad($dataString);
//Encrypt data with AES
$ciphered_data = @mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $aesCipherKey, $dataString, MCRYPT_MODE_CBC, $iv);
return ( $returnBase64Encoded ? base64_encode( $ciphered_data ) : $ciphered_data );
}
catch(Exception $ex){
return null;
}
}
public static function decrypt($dataString, $aesCipherKey, $iv = null, $returnBase64Encoded = false){
// ensure source file exist
if (!$dataString || empty($dataString))
return null;
try{
// ===========
// Ciphering
$ciphered_data = null;
//Decrypt data with AES
$ciphered_data = @mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $aesCipherKey, $dataString, MCRYPT_MODE_CBC, $iv);
//Ensure no pkcs7 padding is left overs
self::pkcs7Strip($ciphered_data);
return ( $returnBase64Encoded ? base64_encode( $ciphered_data ) : $ciphered_data );
}
catch(Exception $ex){
return null;
}
}
EDIT: Remember that you will need to comply to U.S. export laws for software that contains encryption.