美文网首页iOSfish的iOSiOS面试知识点收集
iOS加密解密:AES,DES,3DES,BLOWFISH(含有

iOS加密解密:AES,DES,3DES,BLOWFISH(含有

作者: R4L | 来源:发表于2016-05-27 18:03 被阅读2726次

    (更新了代码,删除padding参数,修改了IV校验)

    文章里介绍了不同加密模式下参数的限制条件,源码里也包含了条件判断,以帮助大家理解CommonCrypto的使用

    此加解密工具包含了:

    对NSData的AES,DES,3DES,BLOWFISH加密解密方法。

    以及对NSData和NSString的MD5,SHA1,SHA2的计算。

    主要依赖于 CommonCrypto 库,本工具并未包含所有加密方法(如:RC4,RC2,CAST)。

    BuffKit源码及Demo地址:

    https://github.com/FlashHand/BuffKit/tree/master/BuffKit/CryptoBuff

    https://github.com/FlashHand/BuffKit

    以Blowfish加解密为例子:

    NSString *sourceStr=@"12345678901234561";
    NSData *source=[sourceStr dataUsingEncoding:NSUTF8StringEncoding];
    [source bfCryptoBlowfishEncodeWithMode:BuffCryptoModeCFB8 iv:@"1234567812345678" key:@"1234567812345678" completion:^(NSData *cryptoData) {    
    [cryptoData bfCryptoBlowfishDecodeWithMode:BuffCryptoModeCFB8 iv:@"1234567812345678" key:@"1234567812345678" completion:^(NSData *cryptoData2) {        
    NSString *result = [[NSString alloc] initWithData: cryptoData2 encoding: NSUTF8StringEncoding];        
    NSLog(@"%@",result);    
    }];
    
    

    上面包含了encode和decode过程。

    打印结果为:12345678901234561

    参数详细说明:

    BuffCryptoMode 为加密模式,支持的加密模式有

    typedef NS_ENUM(NSInteger, BuffCryptoMode) {
        BuffCryptoModeECB       = 1,//kCCModeECB
        BuffCryptoModeCBC       = 2,//kCCModeCBC
        BuffCryptoModeCFB       = 3,//kCCModeCFB
        BuffCryptoModeCTR       = 4,//kCCModeCTR
        BuffCryptoModeOFB       = 7,//kCCModeOFB
        BuffCryptoModeCFB8      = 10,//kCCModeCFB8
    };
    

    并不推荐使用ECB,因为安全性较差。下图表明了,如果对一个位图进行AES-ECB加密甚至会保留原图的一些特征。

    ws

    iv 为初始化偏移量(initialization vector)ECB下填写会被忽略,
    注意iv的length在AES加密时下是16,否则是8,iv的size必须和cypher block size 一致,iv官方注释:

    /*
            iv              Initialization vector, optional. Used for 
                                    Cipher Block Chaining (CBC) mode. If present, 
                                    must be the same length as the selected 
                                    algorithm's block size. If CBC mode is
                                    selected (by the absence of any mode bits in 
                                    the options flags) and no IV is present, a 
                                    NULL (all zeroes) IV will be used. This is 
                                    ignored if ECB mode is used or if a stream 
                                    cipher algorithm is selected. 
    */
    /*!
        @enum           Block sizes
        
        @discussion     Block sizes, in bytes, for supported algorithms. 
        
        @constant kCCBlockSizeAES128    AES block size (currently, only 128-bit 
                                        blocks are supported).
        @constant kCCBlockSizeDES       DES block size.
        @constant kCCBlockSize3DES      Triple DES block size.
        @constant kCCBlockSizeCAST      CAST block size.
    */
    enum {
        /* AES */
        kCCBlockSizeAES128        = 16,
        /* DES */
        kCCBlockSizeDES           = 8,
        /* 3DES */
        kCCBlockSize3DES          = 8,
        /* CAST */
        kCCBlockSizeCAST          = 8,
        kCCBlockSizeRC2           = 8,
        kCCBlockSizeBlowfish      = 8,
    };
    
    

    key 是密钥,AES加密时key的长度必须是16,24,32其中一个,

    DES加密时是8,3DES加密时是24,

    blowfish加密时key的长度可以是整数区间[8,56]中的任意一个.


    加密过程是在GLOBAL_QUEUE里执行的,completion block是异步回调,

    block传入一个NSData类的参数cryptoData,加密或解密失败时cryptoData=nil.


    <h3 id="1">关于padding</h3>
    注意:在ECB或CBC情况下,当原文长度无法被key.length整除时,会对原内容进行补位(padding),默认用PKCS7Padding,否则加密就会失败,补位方法如下:

    while (sourceM.length % key.length != 0) {   
    int pad = 0x07;    
    NSData *padData = [[NSData alloc] initWithBytes:&pad length:1];    
    [sourceM appendData:padData];
    }
    

    在CFB,CTR,OFB,CFB8下无需padding,因为密文和原文大小是一样的,具体参考可参考http://www.di-mgt.com.au/cryptopad.html

    若需要自定义实现或了解实现方式可以看源码

    https://github.com/FlashHand/BuffKit

    如果你有任何问题,欢迎通过简书留言:)

    相关文章

      网友评论

      • _涼城:不知道你有没有注意过 Demo下 AES-CTR、AES-CFB 几个模式的结果问题
        R4L:@_涼城 你说的没错,我改一下 PKCS7和PKCS5填充的数字大小应该等于需要填充的字节数量,这里是我遗漏了,“https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7”
        _涼城:@R4L 嗯嗯 关于这几个模式 我研究了一下 还是不通
        R4L:凉了好久了,最近打算检查下
      • _涼城:关于_buffCipherByUsingString 这个函数 padding7填充补位的操作 应该是缺几位补几位的几,例如 缺6位补0x06,而不是固定的0x07
        _涼城:可以将int pad = 0x07 改为 int pad = (short) (key.length - sourceM.length % key.length ); 尝试一下
      • 6de54c2e26a0:加密后的长度是工具密文的长度的2倍,左边一般是一样的,如后修改参数只取得左半边。作者
        6de54c2e26a0:blowfish的那种
      • 49c292f17dc0:用的是blowfish,和后台加密结果不一样,后台也是7填充的
      • 49c292f17dc0:为啥我加密的和后台加密的不一样呢
      • 闭眼_聆听世界:.h iv key 要求NSDATA ,
        .m 要求全是string ?
        需求还是什么
      • ca7508dad23b:谢谢您的代码,另外话说 3des api .h入口,和.m文件,方法名里的参数有所错误,比如解byte应该是nsdata而不是nsstring,有两个方法正好反了。

        另外对于我这样的小白来说,padding这个东西也是看了下代码才搞明白。
        我key是24位,ecb,但是要解密的32位原密不应该padding, 默认的padding7反倒多了不该有的东西。

        所以对于 原密一定要整除key.length我还是存疑,最后我去掉了您的padding部分就可以了..
        是不是加个padding参数会对我们使用者更方便呢?望指教。
      • 阙笙:楼主的问题改好了么?我去git下载一个?
      • 阙笙:厉害.
      • 沐时:楼主,后台给了一个8位key,一个24位iv,然后进行des3加密,这个转的思路怎么处理呀
        沐时:@R4L 对 我看反了 是8位IV,24位的KEY
        R4L:@雨天太阳 真是长度24的IV的话,你们难道是拆成三个8位IV用的?
        R4L:@雨天太阳 我上面有个地方写错了,就是IV长度是16或8,取决于加密区块大小(AES是16,其它的是8)。比如DES和3DES加密时的IV长度必须为8,超过则会截取前8位,8位的KEY做3DES加密我想应该是用DES进行EDE处理(即:加密解密再加密),解密则是相反是做DED(解密加密再解密)处理,每次都是用同一个密钥,安全性和DES是一样的。24位IV我就看不懂了,你确定不是8位IV,24位的KEY么
      • 萧城x:关于逆向 关于安全 你给了专业的解答
      • 萧城x:MD5 实际是可以被解密的
        R4L:@低调做事 安全不仅取决于算法,也取决于机制。我想设计加密算法的人不会去考虑绝对安全的问题,而是考虑如何设计出破解难度巨大而效率较高的算法。对于算法的使用者,则需要定制一系列安全规则或对算法进行扩展。当个人或团体发现盗取信息是需要付出他们远不能承担的巨大代价,还会有人去破解么(毕竟不能都像FBI那样,花个几百万刀的纳税人的钱去破解一个系统,而且还只针对特定老版本 :dizzy_face:
        萧城x:@R4L 是的 好像2次md5得破解 是需要收费 没有绝对的安全
        R4L:@低调做事 你这种说法可能会对一些人产生困惑,MD5是摘要算法,是无法解密成原来内容的。只能说可以被破解,通过算法找到能产生相同MD5值的数据(显然这个成本是巨大的)。网上所说的MD5解密,则是通过查询加密记录库来做的。
      • 西风颂:在开发中那些地方需要加密呢?还有就是在加密的地方使用哪种方式加密的比较多呢?
        R4L:@西风颂 扩展里写到的方法其实都蛮常用的,比如和服务器交互的时候,账号密码可能会用AES加密,结合MD5或SHA1进行校验,要求高的话,大部分接口都需要加密.

      本文标题:iOS加密解密:AES,DES,3DES,BLOWFISH(含有

      本文链接:https://www.haomeiwen.com/subject/gwxfdttx.html