代码之家  ›  专栏  ›  技术社区  ›  Thomas Kekeisen

如何在ECB模式下用DES在目标C中加密nsstring?

  •  2
  • Thomas Kekeisen  · 技术社区  · 16 年前

    我正试图在iPhone的目标C中加密nsstring。至少我不想通过使用这个键“testTest”得到类似“tmsbdang64li8wc6nlhxogvfu2ijlguewc0czoshrs=”when I encode“us=foo;pw=bar;pwalg=false;“的字符串。

    我现在的问题是,cccrypt总是返回“4300-参数错误”,我不知道为什么。

    这是我的代码(5小时谷歌和尝试错误的结果):

    NSString *token = @"us=foo;pw=bar;pwAlg=false;";
    NSString *key = @"testtest";
    
    const void *vplainText;
    size_t plainTextBufferSize;
    
    plainTextBufferSize = [token length];
    vplainText = (const void *) [token UTF8String];
    
    CCCryptorStatus ccStatus;
    uint8_t *bufferPtr = NULL;
    size_t bufferPtrSize = 0;
    size_t *movedBytes;
    
    bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
    bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    memset((void *)bufferPtr, 0x0, bufferPtrSize);
    // memset((void *) iv, 0x0, (size_t) sizeof(iv));
    
    
    NSString *initVec = @"init Vec";
    const void *vkey = (const void *) [key UTF8String];
    const void *vinitVec = (const void *) [initVec UTF8String];
    
    ccStatus = CCCrypt(kCCEncrypt,
                       kCCAlgorithmDES,
                       kCCOptionECBMode,
                       vkey, //"123456789012345678901234", //key
                       kCCKeySizeDES,
                       NULL,// vinitVec, //"init Vec", //iv,
                       vplainText, //"Your Name", //plainText,
                       plainTextBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       movedBytes);
    
    NSString *result;
    NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
    result = [myData base64Encoding];
    
    1 回复  |  直到 15 年前
        1
  •  10
  •   crafterm    16 年前

    ECB模式下的DES加密使用8字节块大小,并分别对每个块进行编码。问题是,输入字符串不能平均分为8个字节,密码器不知道如何处理最后的非8字节块。

    修复方法是允许加密程序通过在cccrypt的选项中添加kcopionpkcs7 padding来填充最后一个块。例如(nsdata加密类别中的代码段):

    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, 
                                          kCCAlgorithmDES, 
                                          kCCOptionPKCS7Padding | kCCOptionECBMode,
                                          keyPtr, 
                                          kCCKeySizeDES,
                                          NULL, 
                                          [self bytes], 
                                          dataLength,
                                          buffer, 
                                          bufferSize
                                          &numBytesEncrypted);
    

    看看这个 post 有关填充算法的详细信息。希望这有帮助。