如何在iOS中实现Blowfish算法

时间:2012-11-22 07:02:23

标签: iphone ios xcode ipad blowfish

iOS 中实施 BlowFish ECB 加密的最佳方法是什么? 我一直在谷歌搜索并找到了库here。但是没有这个库的文档。不知道如何使用它。

3 个答案:

答案 0 :(得分:5)

我从Bruce Schneier's website获得了Paul Kocher的实施。以下是加密方法的外观:

#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];
}

我在C方面并不擅长,但似乎我的实现工作正常。要解密你需要重复相同的步骤,但是你需要调用 Blowfish_Decrypt 而不是 Blowfish_Encrypt
这是一个源代码(我假设您只是解密密文,但不在这里处理填充):

+ (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;
}

您可能希望返回纯字节或Base64字符串。对于最后一种情况,我有一个类别,它添加了一个初始化器,它使用Base64字符串和一个方法初始化NSData对象,该方法允许从NSData获取Base64字符串。

您还应该考虑使用PADDING_PHRASE,例如,如果您想要添加多个空格,而是添加一些随机字节,该怎么办?在这种情况下,你应该以某种方式发送填充长度。

更新:实际上,您不应在您的流程中使用PADDING_PRASE。相反,您应该使用Wikipedia page

中描述的块密码的标准算法之一

答案 1 :(得分:2)

Apple自己的CommonCrypto API提供(除此之外)Blowfish实现。您可以在CBC(默认)或ECB模式下加密和解密。

请参阅CommonCrypto.h,CommonCryptor.h和CommonCrypto联机帮助页以获取文档。

答案 2 :(得分:2)

我已经为blowfish算法编写了一个原生实现,因为前段时间没有适合我的需求的实现

也许这是一个老问题,但我想帮助那些需要本地类进行blowfish算法的人。

它的作品与PHP完全兼容

  

Objective-C Blowfish实施

     
      
  • 支持EBC和CBC模式
  •   
  • 支持填充RFC和零填充
  •   
  • 兼容PHP&#39; Mcrypt
  •   
  • 最初为iOS SDK编码。它也适用于OS X SDK
  •   

更多关于github;

https://github.com/cantecim/FclBlowfish