Search code examples
objective-cencryptionblowfishecbpkcs#5

How to implement Blowfish ECB algorithm PKCS5 Padding in iOS


I have googled a lot but enable to get Blowfish ECB algorithm with PKCS5 padding in Objective-C.

I have tried code from here but it is not giving me proper encrypted data. Even I have tried codes from here but it is not with PKSC5 padding.

Unfortunately I have to use Blowfish (no other option) to convert following JAVA code in Objective-C

String objVal=<the json>;
SecretKeySpec lKeySpec = new SecretKeySpec(lKey.getBytes("UTF8"),"Blowfish");
Cipher lCipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
lCipher.init(Cipher.ENCRYPT_MODE, lKeySpec);
byte[] lPassword = objVal.getBytes("UTF8");
byte[] lEncryptPassword = lCipher.doFinal(lPassword);
String lEncryptString = new BASE64Encoder().encode(lEncryptPassword);
StringBuffer nString = new StringBuffer();
for (int i = 0; i < lEncryptString.length(); i++) {
int a = lEncryptString.charAt(i);
if (a != 13 && a != 10 && !lEncryptString.substring(i, i + 1).equals(" ")){
nString.append(lEncryptString.charAt(i));
}
return nString.toString();

Then the encrypted json is encoded:

String returnData=<encrypted json>
byte[] inputBytes = returnData.getBytes();
returnData  = DatatypeConverter.printBase64Binary(inputBytes);

Any one has tried and tested solution for Blowfish ECB algorithm with PKSC5 padding.

Thank you in advance.

I know this question is already (several times) asked but either not answered or not with PKCS5 padding


Solution

  • Example code:

    Add Security.framework

    #import <CommonCrypto/CommonCryptor.h>
    
    + (NSData *)doBlowfish:(NSData *)dataIn
                   context:(CCOperation)kCCEncrypt_or_kCCDecrypt
                       key:(NSData *)key
                   options:(CCOptions)options
                        iv:(NSData *)iv
                     error:(NSError **)error
    {
        CCCryptorStatus ccStatus   = kCCSuccess;
        size_t          cryptBytes = 0;
        NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeBlowfish];
    
        ccStatus = CCCrypt( kCCEncrypt_or_kCCDecrypt,
                           kCCAlgorithmBlowfish,
                           options,
                           key.bytes,
                           key.length,
                           (iv)?nil:iv.bytes,
                           dataIn.bytes,
                           dataIn.length,
                           dataOut.mutableBytes,
                           dataOut.length,
                           &cryptBytes);
    
        if (ccStatus == kCCSuccess) {
            dataOut.length = cryptBytes;
        }
        else {
            if (error) {
                *error = [NSError errorWithDomain:@"kEncryptionError"
                                             code:ccStatus
                                         userInfo:nil];
            }
            dataOut = nil;
        }
    
        return dataOut;
    }
    

    Test:

    NSError *error;
    NSData *key = [@"Blowfish" dataUsingEncoding:NSUTF8StringEncoding];
    NSString *stringOriginal = @"TestData";
    NSData *dataOriginal = [stringOriginal dataUsingEncoding:NSUTF8StringEncoding];;
    
    NSLog(@"key %@", key);
    NSLog(@"stringOriginal %@", stringOriginal);
    NSLog(@"dataOriginal   %@", dataOriginal);
    
    NSData *dataEncrypted = [Test doBlowfish:dataOriginal
                                     context:kCCEncrypt
                                         key:key
                                     options:kCCOptionPKCS7Padding | kCCOptionECBMode
                                          iv:nil
                                       error:&error];
    NSLog(@"dataEncrypted  %@", dataEncrypted);
    
    NSString *encryptedBase64String = [dataEncrypted base64EncodedStringWithOptions:0];
    NSLog(@"encryptedBase64String  %@", encryptedBase64String);
    
    
    NSData *dataToDecrypt = [[NSData alloc] initWithBase64EncodedString:encryptedBase64String options:0];
    NSData *dataDecrypted = [Test doBlowfish:dataToDecrypt
                                     context:kCCDecrypt
                                         key:key
                                     options:kCCOptionPKCS7Padding | kCCOptionECBMode
                                          iv:nil
                                       error:&error];
    NSLog(@"dataDecrypted  %@", dataDecrypted);
    
    NSString *stringDecrypted = [[NSString alloc] initWithData:dataDecrypted encoding:NSUTF8StringEncoding];
    NSLog(@"stringDecrypted %@", stringDecrypted);
    

    Output:

    key 426c6f77 66697368
    stringOriginal TestData
    dataOriginal   54657374 44617461
    dataEncrypted  ba5eb956 7e73ae1a b5513ea1 75a14019
    encryptedBase64String  ul65Vn5zrhrdmeYV9B5rQA==
    dataDecrypted  54657374 44617461
    stringDecrypted TestData