zoukankan      html  css  js  c++  java
  • 关于CBC for ios 加密要记

      倒腾了接近半天,资料找了无数,最后是通过查看Android项目中的加密工具类,才弄明白,在这过程中掌握了一些知识点。比如:

    问题1:关于PKCS7Padding和PKCS5Padding

      iOS中AES加密算法采用的填充是PKCS7Padding,而java不支持PKCS7Padding,只支持PKCS5Padding。在IOS中, kCCOptionPKCS7Padding ,其实单单这个参数就是告诉了函数运用CBC加密模式;kCCOptionPKCS7Padding|kCCOptionECBMode,就表示运用了ECB加密模式;在DES中加密数据包单位长度是8字节,在8字节的情况下PKCS7Padding 等价与 PKCS5Padding。

      PKCS7Padding跟PKCS5Padding的区别就在于数据填充方式,PKCS7Padding是缺几个字节就补几个字节的0,而PKCS5Padding是缺几个字节就补充几个字节的几,好比缺6个字节,就补充6个字节的6 。

    问题2:关于Des和3DES

      Cipher cipher=Cipher.getInstance("DESede/CBC/PKCS5Padding");

            a.DESede加密算法的名称,如DESede实际上是3-DES。这一段还可以放其它的对称加密算法,如Blowfish等  

        b.CBC是分组加密的模式,除了CBC和ECB之外,还可以是NONE/CFB/QFB等。最常用的就是CBC和ECB了。DES采用分组加密的方式,将明文按8字节(64位)分组分别加密。如果每个组独立处理,则是ECB。CBC的处理方式是先用初始向量IV对第一组加密,再用第一组的密文作为密钥对第二组加密,然后依次完成整个加密操作。如果明文中有两个分组的内容相同,ECB会得到完全一样的密文,但CBC则不会。

        c.最后一个分组的填充方式。大部分情况下,明文并非刚好64位的倍数。对于最后一个分组,如果长度小于64位,则需要用数据填充至64位。PKCS5Padding是常用的填充方式,如果没有指定,默认的方式就是它。

        ps:补充一点,虽然DES的有效密钥长度是56位,但要求密钥长度是64位(8字节)。3DES则要求24字节。

    问题3:关于中文加密不正确

      通过代码1加密的密文与Android段加密的不一致(汉字),所以改段代码有些不正确,请用代码2

    最后附上一段玩具代码1:

     1 NSString *cryptionKey = @"xxxxxxxxxxx";
     2           NSString *ciphertext = nil;
     3           const char *textBytes = [_pwdTextField.text UTF8String];
     4          NSUInteger dataLength = [_pwdTextField.text length];
     5          unsigned char buffer[1024];
     6          memset(buffer, 0, sizeof(char));
     7           const void *iv = (const void *)[aString UTF8String];
     8          size_t numBytesEncrypted = 0;
     9          CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithm3DES,
    10                                                kCCOptionPKCS7Padding,
    11                                               [cryptionKey UTF8String], kCCKeySize3DES,
    12                                                iv,
    13                                                textBytes, dataLength,
    14                                                buffer, 1024,
    15                                                &numBytesEncrypted);
    16          if (cryptStatus == kCCSuccess) {
    17              NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
    18              NSString *astring1 = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    19              NSLog(@"dds:%@", astring1);
    20             ciphertext = [[NSString alloc] initWithData:[GTMBase64 encodeData:data] encoding:NSUTF8StringEncoding];
    21             
    22         }

     代码2:

     1 NSString *cryptionKey = @"xxxxxxxxxxxx";
     2         NSData *adata = [[NSData alloc] initWithBytes:ivKey length:8];
     3         NSString *iV = [[NSString alloc] initWithData:adata encoding:NSUTF8StringEncoding];
     4         
     5         
     6         NSData* data = [_userNameTextField.text dataUsingEncoding:NSUTF8StringEncoding];
     7         size_t plainTextBufferSize = [data length];
     8         const void *vplainText = (const void *)[data bytes];
     9         
    10         CCCryptorStatus ccStatus;
    11         uint8_t *bufferPtr = NULL;
    12         size_t bufferPtrSize = 0;
    13         size_t movedBytes = 0;
    14         
    15         bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
    16         bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    17         memset((void *)bufferPtr, 0x0, bufferPtrSize);
    18         
    19         const void *vkey = (const void *) [cryptionKey UTF8String];
    20         const void *vinitVec = (const void *) [iV UTF8String];
    21         
    22         ccStatus = CCCrypt(kCCEncrypt,
    23                            kCCAlgorithm3DES,
    24                            kCCOptionPKCS7Padding,
    25                            vkey,
    26                            kCCKeySize3DES,
    27                            vinitVec,
    28                            vplainText,
    29                            plainTextBufferSize,
    30                            (void *)bufferPtr,
    31                            bufferPtrSize,
    32                            &movedBytes);
    33         
    34         NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
    35         NSString *result = [GTMBase64 stringByEncodingData:myData];

    资料链接:

      http://blog.csdn.net/u010184533/article/details/38975871

          http://www.cocoachina.com/bbs/read.php?tid-273195-page-3.html

      http://www.cnblogs.com/qkhh/p/4683626.html   

        http://www.programering.com/a/MzN1cjNwATQ.html

    其他资料:

      http://www.jianshu.com/p/98610bdc9bd6

      https://my.oschina.net/tinglanrmb32/blog/351021

  • 相关阅读:
    拦截器实现对用户是否登录及登陆超时的验证
    Spring+Websocket实现消息的推送
    经典 socket通讯 -- 已验证
    Unity编辑器扩展之RequireComponent等详解
    如何理解着色器,渲染管线,光栅化等概念?
    Unity3D研究院编辑器之脚本设置ToolBar及脚本设置顶视图
    Unity3D研究院编辑器之重写Hierarchy的右键菜单
    Unity3D研究院编辑器之自定义默认资源的Inspector面板
    Unity3D研究院之拓展系统自带组件的Inspector视图
    Unity3D研究院之Inspector视图中的get/set使用
  • 原文地址:https://www.cnblogs.com/royi123/p/7088260.html
Copyright © 2011-2022 走看看