Unable to do AES 128 bit encryption with 1024 iterations - iOS and C# .NET

admin

Administrator
Staff member
I am using 128 bit AES encryption with 1024 iterations for encryption in .NET, using this article as a reference:

<a href="http://steelmon.wordpress.com/2013/07/01/simple-interoperable-encryption-in-java-and-net/" rel="nofollow">http://steelmon.wordpress.com/2013/07/01/simple-interoperable-encryption-in-java-and-net/</a>

The .NET code does the encryption fine:

Code:
class Cls_Security
{
    private const int Iterations = 1024; // Recommendation is &gt;= 1000
    private const string SKeyDemo = "AbCdefGHiJklMnOpQ";// "_?73^?dVT3st5har3";
    private const string SaltKeyDemo = "1234567890abcdEFGHi";//"[email protected]&amp;KT3st5har3EY";       
    private const string InitVectorDemo = "ABCDEFGH12345678";

    public static bool EncryptFile(string srcFilename, string destFilename , bool IsDemo)
    {
        bool Res = false;
        var aes = new AesManaged();
        aes.BlockSize = 128;
        aes.KeySize = 128;
        var salt = Encoding.UTF8.GetBytes(SaltKeyDemo);
        var key = new Rfc2898DeriveBytes("", salt, Iterations);
            salt = Encoding.UTF8.GetBytes(SaltKeyDemo);
            key = new Rfc2898DeriveBytes(SKeyDemo, salt, Iterations);
            aes.Key = key.GetBytes(aes.KeySize / 8);

            aes.IV = Encoding.ASCII.GetBytes(InitVectorDemo);

        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;

        ICryptoTransform transform = aes.CreateEncryptor(aes.Key, aes.IV);

        using (var dest = new FileStream(destFilename, FileMode.Create, FileAccess.Write, FileShare.None))
        {
            using (var cryptoStream = new CryptoStream(dest, transform, CryptoStreamMode.Write))
            {
                using (var source = new FileStream(srcFilename, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    source.CopyTo(cryptoStream);
                    Res = true;
                }
            }
        }
        return Res;
    }
}

The Objective-C code doesn't decrypt the file perfectly:

Code:
#import &lt;CommonCrypto/CommonCrypto.h&gt;
#import "TestViewController.h"
#import "RNCryptManager.h"

@interface TestViewController ()

@end

@implementation TestViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    NSString *url = [[NSBundle mainBundle] pathForResource:@"topics" ofType:@"xml"];

    NSData *inputedData = [[NSData alloc] initWithContentsOfFile:url];

    NSString *path = [NSString stringWithFormat:@"%@topics.xml",NSTemporaryDirectory()];

    //this is what i can decrypt
    NSString *key = @"AbCdefGHiJklMnOpQ";


    //on .net side we are using
    NSString *ivKey = @"ABCDEFGH12345678";
    NSString *saltKey = @"1234567890abcdEFGHi";



    if(inputedData)
    {
            NSData *iv    =  [ivKey dataUsingEncoding:NSUTF8StringEncoding];
            NSData *salt  =  [saltKey dataUsingEncoding:NSUTF8StringEncoding]; ;
            NSError *error = nil;
            NSData *resultedData = [RNCryptManager decryptedDataForData:inputedData password:key iv:iv salt:salt error:&amp;error];


        [resultedData writeToFile:path atomically:YES];

        NSLog(@"error === &gt;&gt; %@",error);
        NSLog(@"RESULT PATH ===&gt;&gt;&gt; %@",path);
    }

}

+ (NSData *)doCipher:(NSData *)dataIn
                  iv:(NSData *)iv
                 key:(NSData *)symmetricKey
             context:(CCOperation)encryptOrDecrypt
{

  //int  bytes[] = { 0x0, 0x1, 0x2, 0x3, 0x5, 0x6, 0x7, 0x8, 0xA, 0xB, 0xC, 0xD, 0xF, 0x10, 0x11, 0x12 };
    CCCryptorStatus ccStatus   = kCCSuccess;
    size_t          cryptBytes = 0;    // Number of bytes moved to buffer.
    NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];

    ccStatus = CCCrypt( encryptOrDecrypt,
                       kCCAlgorithmAES128,
                       kCCOptionPKCS7Padding|kCCModeCBC,
                       symmetricKey.bytes,
                       kCCKeySizeAES128,
                       NULL,/*here u can provid iv byte array*/
                       dataIn.bytes,
                       dataIn.length,
                       dataOut.mutableBytes,
                       dataOut.length,
                       &amp;cryptBytes);

    if (ccStatus != kCCSuccess) {
        NSLog(@"CCCrypt status: %d", ccStatus);
    }

    dataOut.length = cryptBytes;

    return dataOut;
}


- (NSData *)AES128DecryptWithKey:(NSString *)key  dataIn:(NSData *)dataIn   iv:(NSData *)iv{
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused) // oorspronkelijk 256
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

    // fetch key data
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [dataIn 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, kCCKeySizeAES128, // oorspronkelijk 256
                                          [iv bytes] /* initialization vector (optional) */,
                                          [dataIn bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &amp;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;
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Could you please tell me what I'm doing wrong and how to get it to work?