How to implement Blowfish algorithm in iOS
Asked Answered
K

3

6

What is the best way to implement BlowFish ECB encryption in iOS??? I have been googling a lot and found the library here. But there are no documentation of this library. Not sure how to use it.

Kelda answered 22/11, 2012 at 7:2 Comment(8)
example-code.com/objc/crypt2_blowfish.asp and code.google.com/p/blowfish-objc/feedsPettish
thanks ACB. But this one is paid library. I am looking for a free source codeKelda
@RatikantaPatra you done ECB encryption in IOS? I am struggling with same issueShuman
@Shuman nopes. I faced a lot of issues. Eventually had to use AESKelda
@RatikantaPatra i am struggling with Decryption, with the help of online tool, i can check decrypted value. I am getting encrypted value from server, I have to decrypt it using blowfish. but i am getting some time Special symbols and some time NUllShuman
@RatikantaPatra please have a look on my new question #19032342Shuman
@RatikantaPatra can you send me any link Regarding AES?Shuman
@Shuman please use the NSData category in the following link:- #11482970Kelda
H
5

I got Paul Kocher implementation from Bruce Schneier's website. And here is how an encryption method may look like:

#define PADDING_PHRASE @"       "

#import "CryptoUtilities.h"
#import "blowfish.h"
#import "NSData+Base64Utilities.h"

@implementation CryptoUtilities

+ (NSString *)blowfishEncrypt:(NSData *)messageData usingKey:(NSData *)secretKey
{
    NSMutableData *dataToEncrypt = [messageData mutableCopy];

    if ([dataToEncrypt length] % 8) {
        NSMutableData *emptyData = [[PADDING_PHRASE dataUsingEncoding:NSUTF8StringEncoding] mutableCopy];
    
        emptyData.length = 8 - [dataToEncrypt length] % 8;
        [dataToEncrypt appendData:emptyData];
    }

    // Here we have data ready to encipher    
    BLOWFISH_CTX ctx;
    Blowfish_Init (&ctx, (unsigned char*)[secretKey bytes], [secretKey length]);
    
    NSRange aLeftRange, aRightRange;
    NSData *aLeftBox, *aRightBox;
    unsigned long dl = 0, dr = 0;
    
    for (int i = 0; i < [dataToEncrypt length]; i += 8) { // Divide data into octets...
        // …and then into quartets
        aLeftRange = NSMakeRange(i, 4);
        aRightRange = NSMakeRange(i + 4, 4);
        
        aLeftBox = [dataToEncrypt subdataWithRange:aLeftRange];
        aRightBox = [dataToEncrypt subdataWithRange:aRightRange];
        
        // Convert bytes into unsigned long
        [aLeftBox getBytes:&dl length:sizeof(unsigned long)];
        [aRightBox getBytes:&dr length:sizeof(unsigned long)];
        
        // Encipher
        Blowfish_Encrypt(&ctx, &dl, &dr);
        
        // Put bytes back
        [dataToEncrypt replaceBytesInRange:aLeftRange withBytes:&dl];
        [dataToEncrypt replaceBytesInRange:aRightRange withBytes:&dr];
    }
    
    return [dataToEncrypt getBase64String];
}

I am not really good in C, but it seems that my implementation works correctly. To decrypt you need just repeat same steps, but instead of Blowfish_Encrypt you need to call Blowfish_Decrypt.
Here is a source code for that (I assume that you just decrypt the cipher text, but don't deal with padding here):

+ (NSData *)blowfishDecrypt:(NSData *)messageData usingKey:(NSData *)secretKeyData
{
    NSMutableData *decryptedData = [messageData mutableCopy];
    
    BLOWFISH_CTX ctx;
    Blowfish_Init (&ctx, (unsigned char*)[secretKeyData bytes], [secretKeyData length]);
    
    NSRange aLeftRange, aRightRange;
    NSData *aLeftBox, *aRightBox;
    unsigned long dl = 0, dr = 0;
    
    for (int i = 0; i< [decryptedData length]; i += 8) { // Divide data into octets...
        // …and then into quartets
        aLeftRange = NSMakeRange(i, 4);
        aRightRange = NSMakeRange(i + 4, 4);
        
        aLeftBox = [decryptedData subdataWithRange:aLeftRange];
        aRightBox = [decryptedData subdataWithRange:aRightRange];
        
        // Convert bytes into unsigned long
        [aLeftBox getBytes:&dl length:sizeof(unsigned long)];
        [aRightBox getBytes:&dr length:sizeof(unsigned long)];
        
        // Decipher
        Blowfish_Decrypt(&ctx, &dl, &dr);
        
        // Put bytes back
        [decryptedData replaceBytesInRange:aLeftRange withBytes:&dl];
        [decryptedData replaceBytesInRange:aRightRange withBytes:&dr];
    }
    
    return decryptedData;
}

You might want to return pure bytes or Base64 string. For the last case I have a category, which adds an initialiser, which initialises NSData object with Base64 string and a method, which allows to get Base64 string from NSData.

You should also think about playing with PADDING_PHRASE, for example, what if you want to add not just several spaces, but some random bytes? In this case you should send a padding length somehow.

Update: Actually, you should not use PADDING_PRASE in your process. Instead, you should use one of the standard algorithms for block ciphers described on Wikipedia page

Holography answered 10/12, 2012 at 5:11 Comment(9)
Note on your code: You should only add emptyData if [dataToEncrypt length] % 8 != 0.Sneakbox
This is brilliant, I can't quite get to work the other way for decrypt though, do you have a sample code?Provo
@Sneakbox of course, thank you. Actually, I've taken Cryptography course on Coursera and there were some strict rules about padding. You can read about those in Wikipedia article and implement any.Holography
@Provo sorry for late response, I've just updated my answer.Holography
@Holography can you give me file "NSData+Base64Utilities.h" and .mShuman
@Holography please have a look on my question. #19032342Shuman
@Shuman sorry, I wasn't able to reply. Did you solve your problem?Holography
@Holography thanks for reply. yes another developer help me. I completed that task.Shuman
Apple's Common Crypto in the Security.framework supports Blowfish and that is a much better solution than including the encryption code.Acth
F
2

Apple's own CommonCrypto API provides (among other things) a Blowfish implementation. You can encrypt and decrypt in either CBC (the default) or ECB modes.

See CommonCrypto.h, CommonCryptor.h, and the CommonCrypto manpage for documentation.

Finch answered 27/9, 2013 at 21:11 Comment(0)
H
2

I've written a native implementation for blowfish algorithm since there was no implementation to fit my needs some time ago

Maybe this is an old question but i want to help someone who needs a native class for blowfish algorithm.

Its works fully compatible with PHP

An Objective-C Blowfish Implementation

  • Supports EBC and CBC mode
  • Supports padding RFC and Zero padding
  • Works compatible with PHP's Mcrypt
  • Originally coded for iOS SDK. It may work also for OS X SDK

More on github;

https://github.com/cantecim/FclBlowfish

Hecatomb answered 7/1, 2015 at 20:49 Comment(4)
What are the advantages of this over using the one Apple provides, which has been vetted/etc by security experts and will be patched promptly if there are vulnerabilities?Abramabramo
When i wrote this. I couldn't find any blowfish library that works compatible with php for iOS. Shortly there was no alternatives. That's the main case. I didnt know about the apple's blowfish wrapper. First of all its easy to use and easy to understand behind the scene. If it comes to supporting algorithm with patches to vulnerabilities i would surely choose the apple one. In the other hand i do not think the algorithm could cause vulnerabilities. Think it as just a little alternative :P One last thing could you provide me apple's blowfish methods for iOS SDK ?Hecatomb
there could be bugs in the algorithm. It happens all the time. Unless you spend 2 hours every day reading security bulletins you should not be implementing one yourself — you should use one maintained by somebody else.Abramabramo
Its open source you know. Anybody can fork it who wants to fix bugs of algorithm. I didn't created an algorithm i created wrapper for it :) So the developer who will use the library sees the everything under the hood. Its not a problem for that kind a person since they can develop every part of the libraryHecatomb

© 2022 - 2024 — McMap. All rights reserved.