Question

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

http://steelmon.wordpress.com/2013/07/01/simple-interoperable-encryption-in-java-and-net/

The .NET code does the encryption fine:

class Cls_Security
{
    private const int Iterations = 1024; // Recommendation is >= 1000
    private const string SKeyDemo = "AbCdefGHiJklMnOpQ";// "_?73^?dVT3st5har3";
    private const string SaltKeyDemo = "1234567890abcdEFGHi";//"!2S@LT&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:

#import <CommonCrypto/CommonCrypto.h>
#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:&error];


        [resultedData writeToFile:path atomically:YES];

        NSLog(@"error === >> %@",error);
        NSLog(@"RESULT PATH ===>>> %@",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,
                       &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 */
                                          &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?

Was it helpful?

Solution

The same code works, just ensure that the number of iterations and all the other parameters are valid for the encrypted content.

OTHER TIPS

Your decryption method doesn't say it is CBC, which you are using as a cipher mode in the .net.

Change the following code in your decrypt method

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES128, // oorspronkelijk 256
                                          [iv bytes] /* initialization vector (optional) */,
                                          [dataIn bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesDecrypted);

To this

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding|kCCModeCBC,
                                          keyPtr, kCCKeySizeAES128, // oorspronkelijk 256
                                          [iv bytes] /* initialization vector (optional) */,
                                          [dataIn bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesDecrypted);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top