I am trying to do AES128 encryption with key and iv and then convert into hex string.My problem is that when I encrypt string into aes128 and convert into hex it give me a hex string.but when i try this same thing in php I am getting diffrent hex string.So when I try to decrypt php hex string, its decrypted successfully. But when I try to decrypt my hex string in php it's give me special characters.
NSString *str = #"hello";
NSString *key = #"1234abcd5678abcd1234abcd5678abcd";
NSString *IV = #"1234567812345678";
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
NSData* responseData = [data AES128EncryptedDataWithKey:key iv:IV];
NSLog(#"%#",[self hexRepresentationWithSpaces_AS:NO withdata:responseData]);
- (NSData *)AES128Operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv
{
char keyPtr[kCCKeySizeAES128 + 1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
char ivPtr[kCCBlockSizeAES128 + 1];
bzero(ivPtr, sizeof(ivPtr));
if (iv) {
[iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
}
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(operation,
kCCAlgorithmAES,
kCCOptionPKCS7Padding,
keyPtr,
kCCBlockSizeAES128,
ivPtr,
[self bytes],
dataLength,
buffer,
bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
-(NSString*)hexRepresentationWithSpaces_AS:(BOOL)spaces withdata:(NSData*)data
{
const unsigned char* bytes = (const unsigned char*)[data bytes];
NSUInteger nbBytes = [data length];
//If spaces is true, insert a space every this many input bytes (twice this many output characters).
static const NSUInteger spaceEveryThisManyBytes = 4UL;
//If spaces is true, insert a line-break instead of a space every this many spaces.
static const NSUInteger lineBreakEveryThisManySpaces = 4UL;
const NSUInteger lineBreakEveryThisManyBytes = spaceEveryThisManyBytes * lineBreakEveryThisManySpaces;
NSUInteger strLen = 2*nbBytes + (spaces ? nbBytes/spaceEveryThisManyBytes : 0);
NSMutableString* hex = [[NSMutableString alloc] initWithCapacity:strLen];
for(NSUInteger i=0; i<nbBytes; ) {
[hex appendFormat:#"%02X", bytes[i]];
//We need to increment here so that the every-n-bytes computations are right.
++i;
if (spaces) {
if (i % lineBreakEveryThisManyBytes == 0) [hex appendString:#"\n"];
else if (i % spaceEveryThisManyBytes == 0) [hex appendString:#" "];
}
}
return hex ;
}
and In php I am using
$td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv);
mcrypt_generic_init($td, $key, $iv);
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
// mcrypt_module_close($td);
echo $hexdata = bin2hex($encrypted);
echo "<br>";
$bindata = '';
for ($i = 0; $i < strlen($hexdata); $i += 2) {
$bindata .= chr(hexdec(substr($hexdata, $i, 2)));
}
echo $bindata;
echo "<br>";
mcrypt_generic_init($td, $key, $iv);
$decrypted = mdecrypt_generic($td,$encrypted);
mcrypt_generic_deinit($td);
echo "encrypted : ".$encrypted;
echo "<br>";
echo "decrypted : ".$decrypted;
mcrypt is a very old library that does not even implement PKCS#7 compatible padding, which you are obviously using in your iOS code. So at the end you are left with a character representation of the padding, which will probably replaced with replacement characters.
A wrong IV will result in 16 characters being wrong, a wrong key in all characters being wrong. You may also want to match the UTF-8 encoding to be able to display characters with a code point above 0x7F.
Related
I am using openssl_encrypt function available in PHP to get the similar result as the below java code is producing.
But it is all different. Kindly help me.
JAVA CODE
package com.atom.echallan.security.util;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import com.atom.echallan.util.EChallanUtil;
public class AtomAES {
private String password = "8E41C78439831010F81F61C344B7BFC7";
private String salt = "200000054575202";
private static int pswdIterations = 65536 ;
private static int keySize = 256;
private final byte[] ivBytes = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
public AtomAES(){
super();
}
public String encrypt(String plainText, String key, String merchantTxnId) throws Exception
{
this.password = key;
// salt->200000054575202
this.salt = merchantTxnId;
return encrypt(plainText);
}
private String encrypt(String plainText) throws Exception {
byte[] saltBytes = salt.getBytes("UTF-8");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(
password.toCharArray(),
saltBytes,
pswdIterations,
keySize
);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
//encrypt the message
IvParameterSpec localIvParameterSpec = new IvParameterSpec(ivBytes);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //CBC
cipher.init(Cipher.ENCRYPT_MODE, secret,localIvParameterSpec);
byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
return byteToHex(encryptedTextBytes);
}
public String decrypt(String encryptedText, String key, String merchantTxnId) throws Exception {
this.password = key;
this.salt = merchantTxnId;
return decrypt(encryptedText);
}
private String decrypt(String encryptedText) throws Exception {
byte[] saltBytes = salt.getBytes("UTF-8");
byte[] encryptedTextBytes = hex2ByteArray(encryptedText);
// Derive the key
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(
password.toCharArray(),
saltBytes,
pswdIterations,
keySize
);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
// Decrypt the message
IvParameterSpec localIvParameterSpec = new IvParameterSpec(ivBytes);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//CBC
cipher.init(Cipher.DECRYPT_MODE, secret,localIvParameterSpec);
byte[] decryptedTextBytes = null;
decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
return new String(decryptedTextBytes);
}
//Converts byte array to hexadecimal String
private String byteToHex(byte byData[])
{
StringBuffer sb = new StringBuffer(byData.length * 2);
for(int i = 0; i < byData.length; i++)
{
int v = byData[i] & 0xff;
if(v < 16)
sb.append('0');
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase();
}
//Converts hexadecimal String to array of byte
private byte[] hex2ByteArray(String sHexData)
{
byte rawData[] = new byte[sHexData.length() / 2];
for(int i = 0; i < rawData.length; i++)
{
int index = i * 2;
int v = Integer.parseInt(sHexData.substring(index, index + 2), 16);
rawData[i] = (byte)v;
}
return rawData;
}
public static void main(String[] args)throws Exception{
AtomAES aes = new AtomAES();
String data = "mmp_txn=355106|mer_txn=M123|amt=100.0000|";
String encData = aes.encrypt(data, EChallanUtil.ATOM_ENCRYPTION_KEY, "178");
System.out.println("ENC DATA : " + encData);
System.out.println("DEC DATA : " + aes.decrypt(encData, EChallanUtil.ATOM_ENCRYPTION_KEY, "178"));
}
}
PHP CODE
class Encryption {
public function encrypt($data, $key = "4A8A53E16C9C34EA5E77EF9FF7B2FD04", $method = "AES-256-CBC") {
$size = openssl_cipher_iv_length($method);
$iv = substr($key, 0, 16);
// string openssl_pbkdf2 ( string $password , string $salt , int $key_length , int $iterations [, string $digest_algorithm ] )
$hash = openssl_pbkdf2($key,'178','256','65536', 'sha1');
$encrypted = openssl_encrypt($data, $method, $hash, OPENSSL_RAW_DATA, $iv);
return bin2hex($encrypted);
}
public function decrypt($data, $key, $method) {
$size = openssl_cipher_iv_length($method);
$iv = substr($key, 0, $size);
$decrypted = openssl_decrypt($data, $method, $key, false, $iv);
return $decrypted;
}
function pkcs5_pad ($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
}
$text = 'mmp_txn=355106|mer_txn=M123|amt=100.0000|';
//
//$enc = new AESEncryption;
//$enc1 = new CbcCrypt;
$enc2 = new Encryption;
echo $enc2->encrypt($text);
JAVA Result :
ENC DATA : 4BBB37555EFFEF677CEF1B5D55843E50255F65540DF16AFB3F2A0B7B91341E54FB0432EEE2154A947DAD013E8C99822D
PHP Result : c43ba05ae04f68ae18313bc2042595fc70981e0d9421af9d232a3d17a01b5dd8dd8ce702230f6e49d918c9578f9c6944
I dont know why it is happening.
Length of the string is same but result are different.
How to get the similar result as in java?
I have solved your code by using below code Hope this may help you
public function encrypt($data, $key = "4A8A53E16C9C34EA5E77EF9FF7B2FD04", $method = "AES-256-CBC") {
$salt="178";
//Converting Array to bytes
$iv = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
$chars = array_map("chr", $iv);
$IVbytes = join($chars);
$salt1 = mb_convert_encoding($salt, "UTF-8"); //Encoding to UTF-8
$key1 = mb_convert_encoding($key, "UTF-8"); //Encoding to UTF-8
//SecretKeyFactory Instance of PBKDF2WithHmacSHA1 Java Equivalent
$hash = openssl_pbkdf2($key1,$salt1,'256','65536', 'sha1');
$encrypted = openssl_encrypt($data, $method, $hash, OPENSSL_RAW_DATA, $IVbytes);
return bin2hex($encrypted);
}
I am trying to AES128 encryption of a string or NSDictaionary, using following code
NSString *str =#"Hello";
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
NSData *cipher = [data AES128EncryptWithKey:key];
//After that I converts nsdata into hex string
NSLog(#"%#",[self hexRepresentationWithSpaces_AS:NO withdata:cipher]);
-(NSData *)AES128EncryptWithKey:(NSString *)key
{
// ‘key’ should be 16 bytes for AES128
char keyPtr[kCCKeySizeAES128 + 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, kCCKeySizeAES128,
#"1234567812345678" /* 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;
}
-(NSString*)hexRepresentationWithSpaces_AS:(BOOL)spaces withdata:(NSData*)data
{
const unsigned char* bytes = (const unsigned char*)[data bytes];
NSUInteger nbBytes = [data length];
//If spaces is true, insert a space every this many input bytes (twice this many output characters).
static const NSUInteger spaceEveryThisManyBytes = 4UL;
//If spaces is true, insert a line-break instead of a space every this many spaces.
static const NSUInteger lineBreakEveryThisManySpaces = 4UL;
const NSUInteger lineBreakEveryThisManyBytes = spaceEveryThisManyBytes * lineBreakEveryThisManySpaces;
NSUInteger strLen = 2*nbBytes + (spaces ? nbBytes/spaceEveryThisManyBytes : 0);
NSMutableString* hex = [[NSMutableString alloc] initWithCapacity:strLen];
for(NSUInteger i=0; i<nbBytes; ) {
[hex appendFormat:#"%02X", bytes[i]];
//We need to increment here so that the every-n-bytes computations are right.
++i;
if (spaces) {
if (i % lineBreakEveryThisManyBytes == 0) [hex appendString:#"\n"];
else if (i % spaceEveryThisManyBytes == 0) [hex appendString:#" "];
}
}
return hex ;
}
On server side following decryption code added
function decrypt($code) {
//$key = $this->hex2bin($key);
$code = $this->hex2bin($code);
$iv = $this->iv;
$td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv);
mcrypt_generic_init($td, $this->key, $iv);
$decrypted = mdecrypt_generic($td, $code);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return utf8_encode(trim($decrypted));
}
protected function hex2bin($hexdata) {
$bindata = '';
for ($i = 0; $i < strlen($hexdata); $i += 2) {
$bindata .= chr(hexdec(substr($hexdata, $i, 2)));
}
return $bindata;
}
I problem is that on generated encrypt string not decrypting in php
WE are trying to follow this link
Take a look at this code, it will decrypt & encrypt clear text in both ways using AES128 (Rijndael) with CBC and PKCS7 Padding in PHP and C using CommonCrypto in OSX/iOS and MCRYPT in PHP:
OSX/iOS Code in C:
#include <CommonCrypto/CommonCryptor.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Encrypt text */
char *encryptText(const unsigned char *clearText, char myKey[20], char myIv[20])
{
CCCryptorStatus status;
unsigned char cipherKey[kCCKeySizeAES128];
unsigned char cipherIv[kCCKeySizeAES128];
unsigned char cipherText[strlen((const char *)clearText) + kCCBlockSizeAES128];
size_t nEncrypted;
for (int i=0 ; i<kCCKeySizeAES128; i++)
{
cipherKey[i] = myKey[i];
cipherIv[i] = myIv[i];
}
status = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, cipherKey, kCCKeySizeAES128, cipherIv, clearText, strlen((const char *)clearText), cipherText, sizeof(cipherText), &nEncrypted);
if (status != kCCSuccess)
{
printf("CCCrypt() failed with error %d\n", status);
}
size_t cipherSize = nEncrypted;
char *encoded_data = b64_encode((const unsigned char*)cipherText, cipherSize);
return encoded_data;
}
/* Decrypt text */
int decode(unsigned char *dest, const char *buf)
{
char b[3];
int i;
b[2] = 0;
for(i=0; buf[i] ;i+=2)
{
b[0] = buf[i];
b[1] = buf[i+1];
dest[i/2] = (int) strtol(b, NULL, 0x10);
}
return 0;
}
char *decryptText(const unsigned char *cipherText, char myKey[20], char myIv[20])
{
unsigned char cipherKey[kCCKeySizeAES128];
unsigned char cipherIv[kCCKeySizeAES128];
for (int i=0 ; i<kCCKeySizeAES128; i++)
{
cipherKey[i] = myKey[i];
cipherIv[i] = myIv[i];
}
int lenKey = strlen((const char *)cipherKey);
char hex_key[(lenKey*2)+1];
char2hex((char *)cipherKey, hex_key);
int lenIv = strlen((const char *)cipherIv);
char hex_iv[(lenIv*2)+1];
char2hex((char *)cipherIv, hex_iv);
size_t cipherSize = strlen((const char *)cipherText);
unsigned char *decoded_data = b64_decode((const char*)cipherText, cipherSize);
int lenData = strlen((const char *)decoded_data);
char *hexcipherText;
hexcipherText = bin2hex(decoded_data, lenData);
CCCryptorStatus status;
int len = strlen((const char *)hexcipherText) / 2;
unsigned char clearText[len];
unsigned char decodedCipherText[len];
unsigned char decodedKey[len];
unsigned char decodedIv[len];
size_t nDecrypted;
int i;
decode(decodedKey, (const char *)hex_key);
decode(decodedCipherText, (const char *)hexcipherText);
decode(decodedIv, (const char *)hex_iv);
status = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, decodedKey, kCCKeySizeAES128, decodedIv, decoded_data, len, clearText, sizeof(clearText), &nDecrypted);
if (status != kCCSuccess)
{
printf("CCCrypt() failed with error %d\n", status);
}
int extraInfo = strlen((const char *)clearText);
char* toReturn = malloc(extraInfo + 1);
strcpy(toReturn, (const char *)clearText);
strcat(toReturn, "\0");
return toReturn;
}
Note the base64 encode & decode function (b64_encode, b64_decode):
#ifdef b64_USE_CUSTOM_MALLOC
extern void* b64_malloc(size_t);
#endif
#ifdef b64_USE_CUSTOM_REALLOC
extern void* b64_realloc(void*, size_t);
#endif
int bufc = 0;
char* b64_buf_malloc()
{
char* buf = b64_malloc(B64_BUFFER_SIZE);
bufc = 1;
return buf;
}
char* b64_buf_realloc(unsigned char* ptr, size_t size)
{
if (size > bufc * B64_BUFFER_SIZE)
{
while (size > bufc * B64_BUFFER_SIZE) bufc++;
char* buf = b64_realloc(ptr, B64_BUFFER_SIZE * bufc);
if (!buf) return NULL;
return buf;
}
return (char *)ptr;
}
/* Encode in b64 */
char *b64_encode(const unsigned char *src, size_t len)
{
int i = 0;
int j = 0;
char *enc = NULL;
size_t size = 0;
unsigned char buf[4];
unsigned char tmp[3];
enc = (char *) b64_buf_malloc();
if (NULL == enc) { return NULL; }
while (len--)
{
tmp[i++] = *(src++);
if (3 == i)
{
buf[0] = (tmp[0] & 0xfc) >> 2;
buf[1] = ((tmp[0] & 0x03) << 4) + ((tmp[1] & 0xf0) >> 4);
buf[2] = ((tmp[1] & 0x0f) << 2) + ((tmp[2] & 0xc0) >> 6);
buf[3] = tmp[2] & 0x3f;
enc = (char *) b64_buf_realloc((unsigned char *)enc, size + 4);
for (i = 0; i < 4; ++i)
{
enc[size++] = b64_table[buf[i]];
}
i = 0;
}
}
if (i > 0)
{
for (j = i; j < 3; ++j)
{
tmp[j] = '\0';
}
buf[0] = (tmp[0] & 0xfc) >> 2;
buf[1] = ((tmp[0] & 0x03) << 4) + ((tmp[1] & 0xf0) >> 4);
buf[2] = ((tmp[1] & 0x0f) << 2) + ((tmp[2] & 0xc0) >> 6);
buf[3] = tmp[2] & 0x3f;
for (j = 0; (j < i + 1); ++j)
{
enc = (char *) b64_buf_realloc((unsigned char *)enc, size + 1);
enc[size++] = b64_table[buf[j]];
}
while ((i++ < 3))
{
enc = (char *) b64_buf_realloc((unsigned char *)enc, size + 1);
enc[size++] = '=';
}
}
enc = (char *) b64_buf_realloc((unsigned char *)enc, size + 1);
enc[size] = '\0';
return enc;
}
/* Decode b64 */
unsigned char *b64_decode(const char *src, size_t len)
{
return b64_decode_ex(src, len, NULL);
}
unsigned char *b64_decode_ex(const char *src, size_t len, size_t *decsize)
{
int i = 0;
int j = 0;
int l = 0;
size_t size = 0;
unsigned char *dec = NULL;
unsigned char buf[3];
unsigned char tmp[4];
dec = (unsigned char *) b64_buf_malloc();
if (NULL == dec) { return NULL; }
while (len--)
{
if ('=' == src[j]) { break; }
if (!(isalnum(src[j]) || '+' == src[j] || '/' == src[j])) { break; }
tmp[i++] = src[j++];
if (4 == i)
{
for (i = 0; i < 4; ++i)
{
for (l = 0; l < 64; ++l)
{
if (tmp[i] == b64_table[l])
{
tmp[i] = l;
break;
}
}
}
buf[0] = (tmp[0] << 2) + ((tmp[1] & 0x30) >> 4);
buf[1] = ((tmp[1] & 0xf) << 4) + ((tmp[2] & 0x3c) >> 2);
buf[2] = ((tmp[2] & 0x3) << 6) + tmp[3];
dec = (unsigned char *) b64_buf_realloc(dec, size + 3);
if (dec != NULL)
{
for (i = 0; i < 3; ++i)
{
dec[size++] = buf[i];
}
}
else
{
return NULL;
}
i = 0;
}
}
if (i > 0)
{
for (j = i; j < 4; ++j)
{
tmp[j] = '\0';
}
for (j = 0; j < 4; ++j)
{
for (l = 0; l < 64; ++l)
{
if (tmp[j] == b64_table[l])
{
tmp[j] = l;
break;
}
}
}
buf[0] = (tmp[0] << 2) + ((tmp[1] & 0x30) >> 4);
buf[1] = ((tmp[1] & 0xf) << 4) + ((tmp[2] & 0x3c) >> 2);
buf[2] = ((tmp[2] & 0x3) << 6) + tmp[3];
dec = (unsigned char *)b64_buf_realloc(dec, size + (i - 1));
if (dec != NULL)
{
for (j = 0; (j < i - 1); ++j)
{
dec[size++] = buf[j];
}
}
else
{
return NULL;
}
}
dec = (unsigned char *)b64_buf_realloc(dec, size + 1);
if (dec != NULL)
{
dec[size] = '\0';
}
else
{
return NULL;
}
if (decsize != NULL)
{
*decsize = size;
}
return dec;
}
Also note the bin2hex & char2hex function:
/* Char to Hex conversion */
void char2hex(char* input, char* output)
{
int loop;
int i;
i=0;
loop=0;
while(input[loop] != '\0')
{
sprintf((char*)(output+i),"%02X", input[loop]);
loop+=1;
i+=2;
}
output[i++] = '\0';
}
/* Bin to Hex conversion */
static char hexconvtab[] = "0123456789abcdef";
static char* bin2hex(const unsigned char *old, const size_t oldlen)
{
char *result = (char*) malloc(oldlen * 2 + 1);
size_t i, j;
for (i = j = 0; i < oldlen; i++)
{
result[j++] = hexconvtab[old[i] >> 4];
result[j++] = hexconvtab[old[i] & 15];
}
result[j] = '\0';
return result;
}
Now, the PHP Code:
/* Encrypt text */
function encRijndael($text, $key, $iv)
{
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$padding = $block - (strlen($text) % $block);
$text .= str_repeat(chr($padding), $padding);
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv);
return base64_encode($crypttext);
}
/* Decrypt Text */
function decRijndael($encrypted, $key, $iv)
{
$iv_utf = mb_convert_encoding($iv, 'UTF-8');
$toreturn = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($encrypted), MCRYPT_MODE_CBC, $iv_utf);
$toreturn = filter_var($toreturn, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
return $toreturn;
}
I learned this code reading the book O'Reilly, Hacking and Securing iOS Applications from Jonathan Zdziarski.
I have the following Visual Basic .NET function that is used to encrypt a file. This function is from third party so I cannot alter the original code.
Dim bytes As Byte() = New UnicodeEncoding().GetBytes("12345678")
Dim fileStream1 As FileStream = New System.IO.FileStream(txtInput.Text, FileMode.Create)
Dim rijndaelManaged As RijndaelManaged = New RijndaelManaged
Dim cryptoStream1 As CryptoStream = New CryptoStream(fileStream1, rijndaelManaged.CreateEncryptor(bytes, bytes), CryptoStreamMode.Write)
Dim fileStream2 As FileStream = New System.IO.FileStream(txtOutput.Text, FileMode.Open)
Dim BytesRead As Integer
Dim buffer(4096) As Byte
Do
BytesRead = fileStream2.Read(buffer, 0, buffer.Length)
If BytesRead > 0 Then
cryptoStream1.Write(buffer, 0, BytesRead)
End If
Loop While BytesRead > 0
I need help creating a PHP to decrypt the above function. Currently I tried to decrypt using this function in PHP:
function decrypt($text) {
$key = mb_convert_encoding("12345678","utf-16");
$iv = mb_convert_encoding("12345678","utf-16");
return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv), "\0");
}
$decrypted=decrypt(file_get_contents("tes_encrypted.xml"));
$nfile = fopen("test.xml", 'w');
fwrite($nfile, $decrypted);
fclose($nfile);
As you can see the encryption function in VB.NET use a predefined Key and IV. It also doesn't specify a padding method. The PHP function generates different result.
Finally I got the answer. Here the correct PHP code to decrypt the VB.NET encryption above:
function unpad($value)
{
$blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$packing = ord($value[strlen($value) - 1]);
if($packing && $packing < $blockSize)
{
for($P = strlen($value) - 1; $P >= strlen($value) - $packing; $P--)
{
if(ord($value{$P}) != $packing)
{
$packing = 0;
}
}
}
return substr($value, 0, strlen($value) - $packing);
}
function decrypt($text) {
$key= mb_convert_encoding("12345678","ucs-2LE");
$iv= mb_convert_encoding("12345678","ucs-2LE");
return unpad(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv));
}
I am uploading an image to PHP from an iPhone but in PHP the image is not visible. The image was saving in bytes.
-(void)uploadMyImage:(UIImage *)img
{
NSData *data = UIImageJPEGRepresentation(img, 90);
NSMutableString *urlString = [[NSMutableString alloc] init];
[Base64 initialize];
[urlString appendFormat:#"image=%#",[Base64 encode:data]];
NSString *baseurl = #"http://projectleads.info/spirits/images/imageupload1.php" ;
NSData *postData = [urlString dataUsingEncoding:NSUTF8StringEncoding];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSURL *url = [NSURL URLWithString:baseurl];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
[urlRequest setHTTPMethod: #"POST"];
[urlRequest setValue:postLength forHTTPHeaderField:#"Content-Length"];
[urlRequest setValue:#"application/x-www-form-urlencoded"
forHTTPHeaderField:#"Content-Type"];
[urlRequest setHTTPBody:postData];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
[connection start];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
resData=[[NSMutableData alloc]init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[resData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString* newStr = [[NSString alloc] initWithData:resData
encoding:NSUTF8StringEncoding];
}
And my php code is
<?php
$base=$_REQUEST['image'];
if(empty($base))
{
echo 'No data';
}
else
{
echo $base;
$binary=base64_decode($base);
header('Content-Type: bitmap; charset=utf-8');
// print($binary);
//$theFile = base64_decode($image_data);
$dbser='localhost';
$dbuser='spirit';
$dbpwd='123456';
$dbname='spirit';
$db= mysql_connect($dbser,$dbuser,$dbpwd);
$dbcon=mysql_select_db($dbname);
function generate_chars()
{
$num_chars = 4; //max length of random chars
$i = 0;
$my_keys = "123456789abcdefghijklmnopqrstuvwxyz"; //keys to be chosen from
$keys_length = strlen($my_keys);
$url = "";
while($i<$num_chars)
{
$rand_num = mt_rand(1, $keys_length-1);
$url .= $my_keys[$rand_num];
$i++;
}
return $url;
}
function isUnique($chars)
{
//check the uniqueness of the chars
global $link;
$q = "SELECT * FROM `url` WHERE `randname`='".$chars."'";
$r = mysql_query($q, $link);
//echo mysql_num_rows($r); die();
if( mysql_num_rows($r)>0 ):
return false;
else:
return true;
endif;
}
$chars = generate_chars();
while( !isUnique($chars) )
{
$chars = generate_chars();
}
$query=mysql_query("insert into url (randname) values ('".$chars."')");
$test=$chars.".jpg";
$file = fopen($test, 'wb');
fwrite($file, $binary);
fclose($file);
echo 'success';
echo '<img src=test.jpg>';
}
?>
For iPhone :
Check here How to upload Image on PHP Server
Also this Upload Image
And For converting UIImage into String using Base64 Ecoding use Base64 Ecoding Method
I hope this will helps You
Your PHP code is just fine, the problem is in the base 64 encoding. I have successfully uploaded an image with your code, do the following to correctly encode the data.
Copy and paste this method in your code (taken from Creating a base-64 string from NSData)
- (NSString*)base64forData:(NSData*) theData {
const uint8_t* input = (const uint8_t*)[theData bytes];
NSInteger length = [theData length];
static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t* output = (uint8_t*)data.mutableBytes;
NSInteger i;
for (i=0; i < length; i += 3) {
NSInteger value = 0;
NSInteger j;
for (j = i; j < (i + 3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
NSInteger theIndex = (i / 3) * 4;
output[theIndex + 0] = table[(value >> 18) & 0x3F];
output[theIndex + 1] = table[(value >> 12) & 0x3F];
output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '=';
output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '=';
}
return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
}
Now to get the encoded string do
NSString *encodedString = [[self base64forData:data] stringByReplacingOccurrencesOfString:#"+" withString:#"%2B"];
Append the encoded string as follows
[urlString appendFormat:#"image=%#", encodedString];
I have spent a huge amount of time with no success trying to decrypt an encrypted string ("yIH7EYW0e4HuxkHApkG7xQ==") on the PHP server side. The string was encrypted on iOS platform and encoded into text using base64 format.
Anyway, could someone please correct my mistake with the PHP side (I am a little weak on this side)? I am aware the method is not very secure as is. I just need a temporary solution until I can research better methods with openssl.
PHP:
$str_encrypted = "yIH7EYW0e4HuxkHApkG7xQ=="; // base64encoded
$mykey = "my password";
$decrypted = decrypt_data($str_encrypted =, $mykey);
function decrypt_data($str_encrypted =, $mykey)
{
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$decrypted_text = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $encryptionkey, $text, MCRYPT_MODE_ECB, $iv);
return $decrypted_text;
}
IOS:
- (NSString *)AES128EncryptWithKey:(NSString *)key
{
NSData *plainData = [self dataUsingEncoding:NSUTF8StringEncoding];
NSData *encryptedData = [plainData AES128EncryptWithKey:key];
NSString *encryptedString = [encryptedData base64Encoding];
return encryptedString;
}
IOS:
- (NSString *)base64Encoding
{
const unsigned char *bytes = [self bytes];
NSMutableString *result = [NSMutableString stringWithCapacity:self.length];
unsigned long ixtext = 0;
unsigned long lentext = self.length;
long ctremaining = 0;
unsigned char inbuf[3], outbuf[4];
unsigned short i = 0;
unsigned short charsonline = 0, ctcopy = 0;
unsigned long ix = 0;
while( YES )
{
ctremaining = lentext - ixtext;
if( ctremaining <= 0 ) break;
for( i = 0; i < 3; i++ )
{
ix = ixtext + i;
if( ix < lentext ) inbuf[i] = bytes[ix];
else inbuf [i] = 0;
}
outbuf [0] = (inbuf [0] & 0xFC) >> 2;
outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
outbuf [3] = inbuf [2] & 0x3F;
ctcopy = 4;
switch( ctremaining )
{
case 1:
ctcopy = 2;
break;
case 2:
ctcopy = 3;
break;
}
for( i = 0; i < ctcopy; i++ )
[result appendFormat:#"%c", encodingTable[outbuf[i]]];
for( i = ctcopy; i < 4; i++ )
[result appendString:#"="];
ixtext += 3;
charsonline += 4;
}
return [NSString stringWithString:result];
}