navneet83 / Cross-platform-AES-encryption

Basic cross platform AES encryption
Apache License 2.0
320 stars 152 forks source link

Not working in IOS. Please check before using. #53

Open jignesh6990 opened 7 years ago

jignesh6990 commented 7 years ago

Hi,

We need to encrypt/decrypt string between IOS,android and C# app.We have used this class and it works in C# and android but not working in IOS. Please check for IOS compatibility before use.

Regards

jignesh6990 commented 7 years ago

Hi, this works fine with C# and android but not working with IOS. Finally found the below solution which working fine in IOS.

import <CommonCrypto/CommonCryptor.h>

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

    NSString *sData = @"Meet me at the secret location at 8pm";
    NSString *sIv = @"4QesEr03HwE5H1C+ICw7SA==";
    NSString *sKey = @"ovA6siPkyM5Lb9oNcnxLz676K6JK6FrJKk4efEUWBzg=";

    NSData *dData = [sData dataUsingEncoding:NSUTF8StringEncoding];

    NSData *dEncrypt = [self doCipher:dData key:sKey iv:sIv context:kCCEncrypt];
    NSData *base64 = [dEncrypt base64EncodedDataWithOptions:0];
    NSString *sBase64 = [[NSString alloc] initWithData:base64 encoding:NSUTF8StringEncoding];
    NSLog(@"Base64 String: %@",sBase64);

    NSData *dDecrypt= [self decrypt:dEncrypt key:sKey iv:sIv];
    NSString *sDecrypt = [[NSString alloc] initWithData:dDecrypt encoding:NSUTF8StringEncoding];
    NSLog(@"Decrypted Data: %@",sDecrypt);
}

- (NSData *)doCipher:(NSData *)plainText
                 key:(NSString *)key
                  iv:(NSString *)iv
             context:(CCOperation)encryptOrDecrypt
{
    NSUInteger dataLength = [plainText length];

    size_t buffSize = dataLength + kCCBlockSizeAES128;
    void *buff = malloc(buffSize);

    size_t numBytesEncrypted = 0;

    NSData *dIv = [iv dataUsingEncoding:NSUTF8StringEncoding];
    NSData *dKey = [key dataUsingEncoding:NSUTF8StringEncoding];

    CCCryptorStatus status = CCCrypt(encryptOrDecrypt,
                                     kCCAlgorithmAES128,
                                     kCCOptionPKCS7Padding,
                                     dKey.bytes, kCCKeySizeAES256,
                                     dIv.bytes,
                                     [plainText bytes], [plainText length],
                                     buff, buffSize,
                                     &numBytesEncrypted);
    if (status == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buff length:numBytesEncrypted];
    }

    free(buff);
    return nil;
}
grabarz121 commented 7 years ago

I was tried to make an IOS implementation working, but with no success. Alternative fr this example is CryptoSwift library its working with C# and Android examples. Its simply to import .xcodeproj file from an github project, and add extension for a String:

import Foundation
import CryptoSwift

extension String {
    func aesEncrypt(key: String, iv: String) throws -> String{
        let data = self.dataUsingEncoding(NSUTF8StringEncoding)
        let enc = try AES(key: key, iv: iv, blockMode:.CBC).encrypt(data!.arrayOfBytes(), padding: PKCS7())
        let encData = NSData(bytes: enc, length: Int(enc.count))
        let base64String: String = encData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0));
        let result = String(base64String)
        return result
    }

    func aesDecrypt(key: String, iv: String) throws -> String {
        let data = NSData(base64EncodedString: self, options: NSDataBase64DecodingOptions(rawValue: 0))
        let dec = try AES(key: key, iv: iv, blockMode:.CBC).decrypt(data!.arrayOfBytes(), padding: PKCS7())
        let decData = NSData(bytes: dec, length: Int(dec.count))
        let result = NSString(data: decData, encoding: NSUTF8StringEncoding)
        return String(result!)
    }
}

Works perfect.