【问题标题】:How to implement Blowfish algorithm in iOS如何在 iOS 中实现 Blowfish 算法
【发布时间】:2012-11-10 12:54:26
【问题描述】:

iOS 中实现 BlowFish ECB 加密的最佳方式是什么??? 我一直在谷歌搜索,找到了图书馆here。但是没有这个库的文档。不知道怎么用。

【问题讨论】:

  • 感谢 ACB。但是这个是付费图书馆。我正在寻找免费的源代码
  • @RatikantaPatra 你在 IOS 中完成了 ECB 加密吗?我正在努力解决同样的问题
  • @QueueOverFlow 不。我遇到了很多问题。最终不得不使用AES
  • @RatikantaPatra 我正在努力解密,借助在线工具,我可以检查解密的值。我从服务器获取加密值,我必须使用河豚对其进行解密。但我得到了一些时间特殊符号和一些时间 NUll

标签: iphone ios xcode ipad blowfish


【解决方案1】:

我已经为河豚算法编写了一个本机实现,因为前段时间没有满足我需要的实现

也许这是一个老问题,但我想帮助需要河豚算法本机类的人。

完全兼容 PHP

Objective-C Blowfish 实现

  • 支持 EBC 和 CBC 模式
  • 支持填充 RFC 和零填充
  • 与 PHP 的 Mcrypt 兼容
  • 最初为 iOS SDK 编码。它也可能适用于 OS X SDK

更多在 github 上;

https://github.com/cantecim/FclBlowfish

【讨论】:

  • 与使用 Apple 提供的经过安全专家审查/等并在有漏洞时会及时修补的 Apple 相比有什么优势?
  • 当我写这篇文章的时候。我找不到任何兼容 php for iOS 的河豚库。很快就没有其他选择了。这是主要情况。我不知道苹果的河豚包装纸。首先,它易于使用且易于理解。如果要支持带有漏洞补丁的算法,我肯定会选择苹果。另一方面,我认为该算法不会导致漏洞。认为它只是一个小选择:P 最后一件事你能提供给我苹果的 iOS SDK 河豚方法吗?
  • 算法中可能存在错误。它一直在发生。除非您每天花 2 小时阅读安全公告,否则您不应该自己实现一个 - 您应该使用由其他人维护的一个。
  • 你知道它是开源的。任何想要修复算法错误的人都可以分叉它。我没有创建算法,而是为它创建了包装器 :) 所以将使用该库的开发人员可以看到引擎盖下的所有内容。对于那种人来说这不是问题,因为他们可以开发图书馆的每一个部分
【解决方案2】:

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

有关文档,请参阅 CommonCrypto.h、CommonCryptor.h 和 CommonCrypto 联机帮助页。

【讨论】:

    【解决方案3】:

    我从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 中描述的分组密码的标准算法之一

    【讨论】:

    • 代码注意事项:只有在 [dataToEncrypt length] % 8 != 0 时才应添加 emptyData。
    • 这太棒了,不过我不能用另一种方式来解密,你有示例代码吗?
    • @ggfela 当然,谢谢。实际上,我在 Coursera 上学习过密码学课程,并且有一些关于填充的严格规定。您可以阅读Wikipedia article 中的相关内容并实施任何内容。
    • @perrohunter 抱歉回复晚了,我刚刚更新了我的答案。
    • Apple's Common Crypto in the Security.framework 支持 Blowfish,这是一个比包含加密代码更好的解决方案。
    猜你喜欢
    • 2019-02-27
    • 2013-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    相关资源
    最近更新 更多