I have a XML file on a server encrypted with the RC4 algorithm (http://rc4crypt.devhome.org)
function encrypt ($pwd, $data, $ispwdHex = 0)
{
if ($ispwdHex)
$pwd = #pack('H*', $pwd); // valid input, please!
$key[] = '';
$box[] = '';
$cipher = '';
$pwd_length = strlen($pwd);
$data_length = strlen($data);
for ($i = 0; $i < 256; $i++)
{
$key[$i] = ord($pwd[$i % $pwd_length]);
$box[$i] = $i;
}
for ($j = $i = 0; $i < 256; $i++)
{
$j = ($j + $box[$i] + $key[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
for ($a = $j = $i = 0; $i < $data_length; $i++)
{
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$k = $box[(($box[$a] + $box[$j]) % 256)];
$cipher .= chr(ord($data[$i]) ^ $k);
}
return $cipher;
}
Here is the objective-C code I use to decrypt :
NSData *dataToDecrypt = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.url.com/fileCrypted.xml"]] returningResponse:nil error:nil];
const void *vplainText;
size_t plainTextBufferSize;
plainTextBufferSize = [dataToDecrypt length];
vplainText = [dataToDecrypt bytes];
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
NSString *key = #"mykey";
//NSString *initVec = #"init Vec";
const void *vkey = (const void *) [key UTF8String];
const void *vinitVec = (const void *) [initVec UTF8String];
size_t keyLength = [[key dataUsingEncoding:NSUTF8StringEncoding] length];
ccStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmRC4,
0,
vkey,
kCCKeySizeDES,
nil,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
if (ccStatus == kCCSuccess) NSLog(#"SUCCESS");
/*else*/ if (ccStatus == kCCParamError) return #"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return #"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return #"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return #"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return #"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return #"UNIMPLEMENTED";
NSString *result = [[ NSString alloc ] initWithData: [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSASCIIEncoding];
Logs output : SUCCESS but my result is not good (I tested many encoding but ASCII seems to be the good, cf. PHP function ord ...)
Are my both RC4 implementation standard ?
Edit: removed IV in Objective-C code
Edit2: Objective-C KeyLength = password data length, removed option
If you don't know what you're doing in cryptography, then "rolling-your-own" is a sure fire receipe for disaster. You don't have to believe me, read John Viega on The Cult of Schneier about general programmers who try to "roll their own" cryptography. Paraphrased: Don't do it.
Since this is a file, and I'm guessing a reasonable small file, you can use more standard and higher level libraries using standards such as SSL (OpenSSL and others) or OpenPGP (GPG, etc.) to do the necessary encryption / decryption. I believe there is library or module support for SSL in both Objective-C (or the iPhone environment) and PHP.
In particular about RC4, it is a stream cipher that is deceptively simple to write, but incredibility easy to mess up in its implementation details. See The Misuse of RC4 in Microsoft Word and Excel, and Can you recommend RC4 128-bit encrypted software? for an well known historic example, and a recommendation of security / cryptography expert (former CTO and co-founder of PGP Corp.).
Added:
The keysize in the php script is based on the raw length of the password data. It also does not use any PKCS7 Padding, so I believe that field should be zero (0) (CCryptor doesn't support padding of stream ciphers, and the php version certainly doesn't use it). In your code CCCrypt used a keysize of 8 bytes (64* bits), whereas I believe you want it to be the length (in bytes) of the password (binary data).
There is no MAC or hash of the data so the functions won't be able to determine valid from invalid decodings.
I think this will get you closer to compatibility with this insecure implementation of RC4 (RC4crypt in PHP).
DES uses 56-bits of key from 64-bits of key input.
Building on #mctylr, Avoid rolling your own whenever possible. If you need RC4, use a pre-built/tested library: OpenSSL RC4. You can replace your entire code with about 3 lines.
Related
I'm looking for a way to decrypt a file since a few weeks. But it's impossible to recover the file intact in PHP, only with node. But I would like to do it without node.
If someone can tell me where I could be wrong... ?
I tried with openssl_encrypt/decrypt then with OPENSSL_NO_PADDING & ZERO_PADDING options. Transform the result in base64 but impossible to have the good result...
I thank you in advance I do not know what to do...
Here is my NodeJs crypto code :
decrypt(encryptedBuffer) {
const PASSPHRASE = "";
let decryptedBuffer = Buffer.alloc(encryptedBuffer.length);
let chunkSize = 2048;
let progress = 0;
while (progress < encryptedBuffer.length) {
if ((encryptedBuffer.length - progress) < 2048) {
chunkSize = encryptedBuffer.length - progress;
}
let encryptedChunk = encryptedBuffer.slice(progress, progress + chunkSize);
// Only decrypt every third chunk and only if not at the end
if (progress % (chunkSize * 3) === 0 && chunkSize === 2048) {
let cipher = crypto.createDecipheriv('bf-cbc', PASSPHRASE, Buffer.from([0, 1, 2, 3, 4, 5, 6, 7]));
cipher.setAutoPadding(false);
encryptedChunk = Buffer.concat([cipher.update(encryptedChunk), cipher.final()]);
}
decryptedBuffer.write(encryptedChunk.toString('binary'), progress, encryptedChunk.length, 'binary');
progress += chunkSize;
}
return decryptedBuffer;
}
Here in PHP
public function decrypt($encryptedBuffer)
{
ini_set('memory_limit', '1G');
$f = fopen('myfile', 'wb+');
$chunkSize = 2048;
$progress = 0;
$passphrase = "h5ihb>p9`'yjmkhf";
while ($progress > strlen($encryptedBuffer)) {
// If the buffer is if the end calculate the valid chunksize
if ((strlen($encryptedBuffer) - $progress) < 2048) {
$chunkSize = strlen($encryptedBuffer) - $progress;
}
/** Getting the encrypted chunk part */
$encryptedChunk = substr($encryptedBuffer, $progress, $progress + $chunkSize);
// Only decrypt every third chunk and only if not at the end
if ($progress % ($chunkSize * 3) === 0 && $chunkSize === 2048) {
$encryptedChunk = openssl_decrypt($encryptedChunk, 'bf-cbc', $passphrase, OPENSSL_ZERO_PADDING, '01234567');
}
fwrite($f, $encryptedChunk);
$progress += $chunkSize;
}
}
There are several flaws in the PHP code:
The condition in the while loop is wrong and should be:
$progress < strlen($encryptedBuffer).
$encryptedChunk is determined incorrectly because substr() expects the length in the third parameter. The correct way is:
$encryptedChunk = substr($encryptedBuffer, $progress, $chunkSize);
In the openssl_decrypt() call, too few flags are set in the fourth parameter:
Apart from disabling the padding, the default Base64 decoding has to be disabled with OPENSSL_RAW_DATA.
For key sizes smaller than 16 bytes, the padding of the key with 0x00 values to a length of 16 bytes has to be disabled with OPENSSL_DONT_ZERO_PAD_KEY. This is a PHP bug (s. here). The fix, i.e. the flag is available as of version 7.1.8.
Overall: OPENSSL_DONT_ZERO_PAD_KEY | OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING.
The wrong IV is used, correct would be: hex2bin('0001020304050607').
With these changes, decryption with the PHP code works.
Regarding security: The short block size makes Blowfish vulnerable to birthday attacks, see here. Using a static IV is generally insecure. Rather, a random IV should be generated for each encryption.
I don't really want to dump some code and expect answers but this is a pretty lengthy function that hashes a password in order to later compare it to the database-stored value.
I have seen posts where people wasted time trying to recreate what they could achieve with the md5() function in PHP.
For that reason, I'm wondering if someone with any encryption knowledge knows of a PHP equivalent to achieve the following effect in PHP:
internal static string GenerateEncryptedPassword(string password, string salt, int iterationCount)
{
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
byte[] saltBytes = Encoding.UTF8.GetBytes(salt);
byte[] iterationCountBytes = BitConverter.GetBytes(iterationCount);
int derivedLength = passwordBytes.Length + saltBytes.Length;
byte[] passwordSaltBytes = new byte[derivedLength];
byte[] pbkdf2Bytes;
string encryptedString;
for (int i = 0; i < passwordBytes.Length; i++)
{
passwordSaltBytes[i] = passwordBytes[i];
}
for (int i = 0; i < saltBytes.Length; i++)
{
passwordSaltBytes[passwordBytes.Length + i] = saltBytes[i];
}
using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, passwordSaltBytes, iterationCount))
{
pbkdf2Bytes = pbkdf2.GetBytes(derivedLength + iterationCountBytes.Length);
}
using (SHA512 sha512 = new SHA512Managed())
{
byte[] hashBytes = sha512.ComputeHash(pbkdf2Bytes);
byte[] hashSaltBytes = new byte[hashBytes.Length + saltBytes.Length];
for (int i = 0; i < hashBytes.Length; i++)
{
hashSaltBytes[i] = hashBytes[i];
}
for (int i = 0; i < saltBytes.Length; i++)
{
hashSaltBytes[hashBytes.Length + i] = saltBytes[i];
}
encryptedString = Convert.ToBase64String(hashSaltBytes);
}
return encryptedString;
}
If it changes anything, I'm using Laravel...
Thank you for any guidance
I hate encryption :D
$user = \App\User::all();
$salt = strtolower($user[2]->Salt);
$password = 'P#$$W0rd';
$dbPassword = $user[2]->Password;
$iterations = 10000;
echo openssl_pbkdf2($password, $salt, 44, $iterations, 'sha512');
Read the PHP manual for password_hash and password_verify. I recommend using BCrypt as the algorithm.
http://php.net/manual/en/function.password-hash.php
http://php.net/manual/en/function.password-verify.php
It's not difficult at all! Good luck! :-)
Also, SHA-512 isn't all that secure. Read here: SHA1 vs md5 vs SHA256: which to use for a PHP login?
I haven't used PHP for years so not sure if there are new ways to do things, but you can produce SHA-512 hashes with OpenSSL: http://php.net/manual/en/function.openssl-digest.php
openssl_digest(pbkdf2Bytes, 'sha512');
To generate salt, it is highly recommended to use secure (unpredictable) randoms. For PHP, see this: PHP random string generator
EDIT:
You can also produce pbkfd2 directly with OpenSSL:
http://php.net/manual/en/function.openssl-pbkdf2.php
Just note the optional parameter in the end of the function signature where you define the digest algorithm.
openssl_pbkdf2(password, saltBytes, keyLength, iterationCount, 'sha512')
When i load in web server a page previously encrypted with BLENC this shows:
Severity: Warning
Message: blenc_compile: Validation of script 'path\to\file\R2k_Controller.php' failed. MD5_FILE: 3f6958c4bee8ba0d4cb3a0e67e0e2bde MD5_CALC: 02998505e69466a2f7f3af5d4555a352
Severity: Error
Message: blenc_compile: Validation of script 'path\to\file\R2k_Controller.php' failed, cannot execute.
Using:
PHP 5.6.14 x64 NTS
Blenc 1.1.4b
IIS 7.5
this is the code where I encrypt:
$oDir = NULL;
if(PHP_SAPI === 'cli'){
$path = $argv[1];
$path2 = '';
if(count($argv)>1){
$oDir = new RecDir($path,false);
while (false !== ($archivo = $oDir->read())) {
if(strstr($archivo,".php") !== FALSE){
$path2=substr_replace($archivo,$path,strpos($archivo,$path),strlen($path));
$source_code = file_get_contents($path2);
blenc_encrypt($source_code, $argv[2] . $path2,$FKEY);
echo($archivo . " >>> " . $argv[2] . $path2 . PHP_EOL);
}
}
$oDir->close();
file_put_contents( $argv[2] ."blenc.key_file", $FKEY."\n"); //, FILE_APPEND
}
else{
echo("Error: parametos incorrectos" . PHP_EOL);
}
}
else{
echo("<html><head>Error</head><body>Acceso denegado!</body></html>");
}
how can I solve this?
EDIT
checking The repository for blenc i found this
for (zend_hash_internal_pointer_reset(php_bl_keys);
zend_hash_get_current_data(php_bl_keys, (void **)&key) == SUCCESS;
zend_hash_move_forward(php_bl_keys)) {
decoded = php_blenc_decode(encoded, *key, script_len - sizeof(blenc_header), &decoded_len TSRMLS_CC);
md5 = emalloc(33);
php_blenc_make_md5(md5, decoded, decoded_len TSRMLS_CC);
if(!strncmp(md5, header->md5, 32)) {
validated = TRUE;
efree(md5);
break;
}
zend_error(E_WARNING, "blenc_compile: Validation of script '%s' failed. MD5_FILE: %s MD5_CALC: %s\n",
file_handle->filename, header->md5, md5);
efree(md5);
md5 = NULL;
efree(decoded);
decoded_len = 0;
}
static void php_blenc_make_md5(char *result, void *data, unsigned int data_len TSRMLS_DC)
{
PHP_MD5_CTX context;
unsigned char digest[16];
PHP_MD5Init(&context);
PHP_MD5Update(&context, data, data_len);
PHP_MD5Final(digest, &context);
make_digest(result, digest);
}
b_byte *php_blenc_decode(void *input, unsigned char *key, int in_len, int *out_len TSRMLS_DC)
{
BLOWFISH_CTX ctx;
unsigned long hi, low;
int i;
b_byte *retval;
Blowfish_Init (&ctx, (unsigned char*)key, strlen(key));
if(in_len % 8) {
zend_error(E_WARNING, "Attempted to decode non-blenc encrytped file.");
return estrdup("");
} else {
retval = emalloc(in_len + 1);
}
memset(retval, '\0', sizeof(retval));
hi = 0x0L;
low = 0x0L;
for(i = 0; i < in_len; i+=8) {
hi |= (unsigned int)((char *)input)[i] & 0xFF;
hi = hi << 8;
hi |= (unsigned int)((char *)input)[i+1] & 0xFF;
hi = hi << 8;
hi |= (unsigned int)((char *)input)[i+2] & 0xFF;
hi = hi << 8;
hi |= (unsigned int)((char *)input)[i+3] & 0xFF;
low |= (unsigned int)((char *)input)[i+4] & 0xFF;
low = low << 8;
low |= (unsigned int)((char *)input)[i+5] & 0xFF;
low = low << 8;
low |= (unsigned int)((char *)input)[i+6] & 0xFF;
low = low << 8;
low |= (unsigned int)((char *)input)[i+7] & 0xFF;
Blowfish_Decrypt(&ctx, &hi, &low);
retval[i] = hi >> 24;
retval[i+1] = hi >> 16;
retval[i+2] = hi >> 8;
retval[i+3] = hi;
retval[i+4] = low >> 24;
retval[i+5] = low >> 16;
retval[i+6] = low >> 8;
retval[i+7] = low;
hi = 0x0L;
low = 0x0L;
}
retval[in_len] = '\0';
*out_len = strlen(retval);
return retval;
}
anyone can explain whats happening here ?
The problem is you’re not putting the proper contents into your blenc.key_file.
blenc_encrypt() explains that it returns a redistributable key that must be saved into the key file. This is not the $encryption_key that you pass to blenc_encrypt() to encrypt the code. It is the key that is used to allow blenc to decrypt the code so that it can be run.
In your code, you are calling blenc_encrypt(), and not saving the redistributable key it returns. You are then appending the encryption key to the key file, which is incorrect.
What you need to do instead is this:
$oDir = NULL;
if(PHP_SAPI === 'cli'){
$path = $argv[1];
$path2 = '';
if(count($argv)>1){
$oDir = new RecDir($path,false);
while (false !== ($archivo = $oDir->read())) {
if(strstr($archivo,".php") !== FALSE){
$path2=substr_replace($archivo,$path,strpos($archivo,$path),strlen($path));
$source_code = file_get_contents($path2);
// Save $redistributable_key and save it to the key file
$redistributable_key = blenc_encrypt($source_code, $argv[2] . $path2,$FKEY);
file_put_contents($argv[2] . "blenc.key_file", $redistributable_key . "\n", FILE_APPEND);
echo($archivo . " >>> " . $argv[2] . $path2 . PHP_EOL);
}
}
$oDir->close();
}
else{
echo("Error: parametos incorrectos" . PHP_EOL);
}
}
else{
echo("<html><head>Error</head><body>Acceso denegado!</body></html>");
}
You'll then need to ensure that the contents of the blenc.key_file that's generated are included in the file specified by blenc.key_file ini directive.
Once you've done that, your encrypted files should load correctly in your web server. You can then distribute your encrypted files and the blenc.key_file to your customers.
The C code you included in your edit is part of blenc's decryption engine. The first part is the main loop for blenc_compile(), which takes a file, decodes it, and (if successful) passes it on to the Zend engine for compilation. The latter two functions are just helpers for generating MD5 digests and driving the actual Blowfish decryption. A full understanding of those is quite complicated, and not necessary to understand and fix the problem.
I 'm stuck. It seems that AES encryption done by PHP cannot be decrypted in windows.
PHP code:
$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128,"12345678", "test", MCRYPT_MODE_CBC));
Windows Code:
"s" has the string which is created by the above response after converting back from base64.
bool Decrypt(char* s,char* key,char* dest)
{
// Create the crypto provider context.
HCRYPTPROV hProvider = NULL;
if (!CryptAcquireContext(&hProvider,
NULL, // pszContainer = no named container
MS_ENH_RSA_AES_PROV, // pszProvider = default provider
PROV_RSA_AES,
0))
return false;
// Construct the blob necessary for the key generation.
aes128keyBlob aes_blob128;
aes_blob128.header.bType = PLAINTEXTKEYBLOB;
aes_blob128.header.bVersion = CUR_BLOB_VERSION;
aes_blob128.header.reserved = 0;
aes_blob128.header.aiKeyAlg = CALG_AES_128;
aes_blob128.keySize = 16;
memcpy(aes_blob128.bytes, key, 16);
HCRYPTKEY hKey = NULL;
if (!CryptImportKey(hProvider,
(BYTE*)(&aes_blob128),
sizeof(aes_blob128),
NULL, //
0, //
&hKey)) {
...
}
// Set Mode
DWORD dwMode = CRYPT_MODE_CBC;
CryptSetKeyParam( hKey, KP_MODE, (BYTE*)&dwMode, 0 );
DWORD length = 16;
BOOL X = CryptDecrypt(hKey,
NULL, // hHash = no hash
TRUE, // Final
0,
(BYTE*)s,
&length);
//int le = GetLastError();
memcpy(dest,s,16);
CryptDestroyKey(hKey);
CryptReleaseContext(hProvider, 0);
}
What could be wrong?
The information you provided is not enough to say for certain but I think that your problem is the key length.
In PHP code you pass "12345678" as a key. And AES128 has a key length of 128bit or 16 bytes.
PHP pads the remaining with zero bytes, as stated in the documentation on mcrypt_encrypt.
In the C++ code you pass only the pointer to your key buffer to Decrypt function. But then you copy 16 bytes from it to the key BLOB:
aes_blob128.keySize = 16;
memcpy(aes_blob128.bytes, key, 16);
Then if you call your function like:
char dest[16];
bool result = Decrypt(string_from_php,"12345678",dest);
than the 8 bytes that happen to reside in memory after the "12345678" constant will be copied to the key blob and passed to CryptImportKey as an actual key. Thus the key in C and in PHP code would be actually different and the decryption will fail due to padding error.
PHP MCRYPT functions are a bit different than the windows decryption functions.
Because the mcrypt function takes the key of any length and converts it to the length required by the algorithm by adding \0 at the end of key string.
Please note to create a key with the specified length required for the encryption by the algorithm on both sides.
use md5 on the key and then convert it to the length required for the algorithm.
See below URL
Encrypt in PHP, Decrypt in C# (WP7 / Silverlight) using AES / Rijndael
http://pumka.net/2009/12/16/rsa-encryption-cplusplus-delphi-cryptoapi-php-openssl-2/
http://www.developer.nokia.com/Community/Wiki/Encrypt-Decrypt_contacts_database_entries_using_Symbian_C%2B%2B
Read it
I droped the MD5 crap out of PHP and C#, and they are now working properly.
Just in case you dropped here looking for the same answer, here is a sample code. Don't forget to make your own key and iv (although those bellow will work, is not recommended to use!)
PHP:
function encrypt128($message) {
$vector = "0000000000000000";
$key = "00000000000000000000000000000000";
$block = mcrypt_get_block_size('rijndael_128', 'cbc');
$pad = $block - (strlen($message) % $block);
$message .= str_repeat(chr($pad), $pad);
$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', '');
mcrypt_generic_init($cipher, $key, $vector);
$result = mcrypt_generic($cipher, $message);
mcrypt_generic_deinit($cipher);
return base64_encode($result);
}
C++
Encrypt-Decrypt contacts database entries using Symbian C++
http://www.developer.nokia.com/Community/Wiki/Encrypt-Decrypt_contacts_database_entries_using_Symbian_C%2B%2B
Headers Required:
#include <cntdb.h> // CContactDatabse,
#include <cntitem.h> //CContactItem,CContactItemFieldSet
http://www.developer.nokia.com/Community/Wiki/Encrypt-Decrypt_contacts_database_entries_using_Symbian_C%2B%2B
Encrypt Contact Fields
void CEncryptContactContainer::EncryptAll()
{
CContactDatabase *contactDB = CContactDatabase::OpenL();
CleanupStack::PushL(contactDB);
TContactIter iter(*contactDB);
TContactItemId aContactId;
//Developer can take Heap based descriptor for large/unknown size of contact items.
TBuf16<70> aValue;
const CContactIdArray* contactArray = contactDB->SortedItemsL();
TInt cnt=contactArray->Count();
for(TInt i=0;i<cnt;i++)
{
CContactItem* contactItem=NULL;
contactItem= contactDB->OpenContactL((*contactArray)[i]);
CleanupStack::PushL(contactItem);
CContactItemFieldSet& fieldSet= contactItem->CardFields();
TInt fieldCount=fieldSet.Count(); // This will give number of contact fields.
for(TInt index=0; index < fieldCount; index++)
{
CContactItemField& field = fieldSet[index];
const CContentType& type = field.ContentType();
if(!(type.ContainsFieldType(KUidContactFieldBirthday)))
{
TPtrC name = contactItem->CardFields()[index].TextStorage()->Text();
aValue.Copy(name);
Encrypt(aValue); // Call real encyption here
contactItem->CardFields()[index].TextStorage()->SetTextL(aValue);
}
} //Inner for loop ends here
contactDB->CommitContactL(*contactItem);
CleanupStack::PopAndDestroy(contactItem);
} //Outer for loop ends here
CleanupStack::PopAndDestroy(contactDB);
}
void CEncryptContactContainer:: Encrypt (TDes& aValue)
{
for(TInt iCount=0; iCount< aValue.Length();iCount++)
{
aValue[iCount]+=3;
}
}
Decrypt Contact Fields
void CEncryptContactContainer::DecryptAll()
{
CContactDatabase *contactDB = CContactDatabase::OpenL();
CleanupStack::PushL(contactDB);
TContactIter iter(*contactDB);
TContactItemId aContactId;
TBuf16<70> aValue;
const CContactIdArray* contactArray = contactDB->SortedItemsL();
TInt cnt=contactArray->Count();
for(TInt i=0;i<cnt;i++)
{
CContactItem* contactItem=NULL;
contactItem= contactDB->OpenContactL((*contactArray)[i]);
CleanupStack::PushL(contactItem);
CContactItemFieldSet& fieldSet= contactItem->CardFields();
TInt fieldCount=fieldSet.Count(); // This will give number of contact fields.
for(TInt index=0; index < fieldCount; index++)
{
CContactItemField& field = fieldSet[index];
const CContentType& type = field.ContentType();
if(!(type.ContainsFieldType(KUidContactFieldBirthday)))
{
TPtrC name = contactItem->CardFields()[index].TextStorage()->Text();
aValue.Copy(name);
Decrypt(aValue);
contactItem->CardFields()[index].TextStorage()->SetTextL(aValue);
}
} //Inner for loop ends here
contactDB->CommitContactL(*contactItem);
CleanupStack::PopAndDestroy(contactItem);
} //Outer for loop ends here
CleanupStack::PopAndDestroy(contactDB);
}
void CEncryptContactContainer:: Decrypt (TDes& aValue)
{
for(TInt iCount=0; iCount< aValue.Length();iCount++)
{
aValue[iCount]-=3;
}
}
C#:
byte[] cripted = EncryptStringToBytes("Test", System.Text.Encoding.UTF8.GetBytes("00000000000000000000000000000000"), System.Text.Encoding.UTF8.GetBytes("0000000000000000"));
I've checked all the related Stack Overflow questions. Also checked the links in that answers but didn't got any usable solution.
Here is my php script and I've nothing to do with this script (as I can't change the script).
function encrypt($message,$secretKey) {
return base64_encode(
mcrypt_encrypt(
MCRYPT_RIJNDAEL_256,
$secretKey,
$message,
MCRYPT_MODE_ECB
)
);
}
I'm unable to decrypt it in Objective C. I've used a number of Categories like Strong Encryption for Cocoa / Cocoa Touch etc, also I followed this question How do I do base64 encoding on iOS?
Here is the objective C codes that I used for decryption (found in cocoa-aes Category NSData+AES.h)
- (NSData *)AESDecryptWithPassphrase:(NSString *)pass
{
NSMutableData *ret = [NSMutableData dataWithCapacity:[self length]];
unsigned long rk[RKLENGTH(KEYBITS)];
unsigned char key[KEYLENGTH(KEYBITS)];
const char *password = [pass UTF8String];
for (int i = 0; i < sizeof(key); i++)
key[i] = password != 0 ? *password++ : 0;
int nrounds = rijndaelSetupDecrypt(rk, key, KEYBITS);
unsigned char *srcBytes = (unsigned char *)[self bytes];
int index = 0;
while (index < [self length])
{
unsigned char plaintext[16];
unsigned char ciphertext[16];
int j;
for (j = 0; j < sizeof(ciphertext); j++)
{
if (index >= [self length])
break;
ciphertext[j] = srcBytes[index++];
}
rijndaelDecrypt(rk, nrounds, ciphertext, plaintext);
[ret appendBytes:plaintext length:sizeof(plaintext)];
NSString* s = [[NSString alloc] initWithBytes:plaintext length:sizeof(plaintext) encoding:NSASCIIStringEncoding];
NSLog(#"%#",s);
}
return ret;
}
Also I tried this decoder
- (NSData*) aesDecryptWithKey:(NSString *)key initialVector:(NSString*)iv
{
int keyLength = [key length];
if(keyLength != kCCKeySizeAES128)
{
DebugLog(#"key length is not 128/192/256-bits long");
///return nil;
}
char keyBytes[keyLength+1];
bzero(keyBytes, sizeof(keyBytes));
[key getCString:keyBytes maxLength:sizeof(keyBytes) encoding:NSUTF8StringEncoding];
size_t numBytesDecrypted = 0;
size_t decryptedLength = [self length] + kCCBlockSizeAES128;
char* decryptedBytes = malloc(decryptedLength);
CCCryptorStatus result = CCCrypt(kCCDecrypt,
kCCAlgorithmAES128 ,
(iv == nil ? kCCOptionECBMode | kCCOptionPKCS7Padding : kCCOptionPKCS7Padding),
keyBytes,
keyLength,
iv,
[self bytes],
[self length],
decryptedBytes,
decryptedLength,
&numBytesDecrypted);
if(result == kCCSuccess){
NSData* d=[NSData dataWithBytesNoCopy:decryptedBytes length:numBytesDecrypted];
NSLog(#"%#",[NSString stringWithUTF8String:[d bytes]]);
return d;
}
free(decryptedBytes);
return nil;
}
From the looks of it, that php function does two things.
mcrypt using MCRYPT_RIJNDAEL_256
base64 encodes the output of (1)
That would by why simply using base64 doesn't work. I'm going to guess from the name that MCRYPT_RIJNDAEL_256 is just AES 256.
Hope that helps.
Edit:
The code you added above looks ok. You just have to base64 decode the data first.
The php script does this:
aes encrypt
base64 encode
So you want to do this in your cocoa app:
base64 decode
aes decrypt
If you're having trouble, you might want to play around and see if you can get cocoa to do the same thing as the php script: encrypt and base64 encode the data. If you can get the output of your encryption function to be the same as the output of the php encryption function, you're in a good place to get it decrypting.