0

我正在使用下面的方法在 iOS 中加密一个字符串


-(NSString *) encrypt:(NSString *) data 
{

    const void *vplainText;
    size_t plainTextBufferSize = [data length];
    vplainText = (const void *) [data UTF8String];
    CCCryptorStatus ccStatus;
    uint8_t *bufferPtr = NULL;
    size_t bufferPtrSize = 0;
    size_t movedBytes = 0;

    bufferPtrSize = (plainTextBufferSize + kCCBlockSizeDES) & ~(kCCBlockSizeDES - 1);
    bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    memset((void *)bufferPtr, 0x0, bufferPtrSize);

    Byte iv [] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef};

    NSString *key = @"complexkey";
    const void *vkey = (const void *) [key UTF8String];

    ccStatus = CCCrypt(kCCEncrypt,
                       kCCAlgorithmDES,
                       kCCOptionPKCS7Padding | kCCOptionECBMode,
                       vkey,
                       kCCKeySizeDES,
                       iv,
                       vplainText,
                       plainTextBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       &movedBytes);

    NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
    NSString *result = [myData base64Encoding];

    // url encode the result
    return (__bridge NSString *) CFURLCreateStringByAddingPercentEscapes(NULL,
                                        (__bridge CFStringRef) result,
                                        NULL,
                                        (__bridge CFStringRef) @"!*'();:@&=+$,/?%#[]",
                                        kCFStringEncodingUTF8);
}

在 php 上,我将字符串解密如下 -


$decrypted = mcrypt_decrypt(MCRYPT_DES, 'complexkey', base64_decode(urldecode($encrypted)), MCRYPT_MODE_ECB);

这似乎在 75% 的时间里都能正常工作,我不确定为什么它在其他时候会失败。有什么线索吗?谢谢您的帮助!

4

2 回答 2

0

它可能是填充,它是两种方法之间唯一不同步的东西。不幸的是,您可能必须创建自己的未填充表单 mcrypt,因为该库不执行 PKCS#5 填充(实际上与 PKCS#7 填充相同)。幸运的是,这相当简单:解密,然后使用最后一个字节的值来剥离最后一个字节。

其他安全相关说明:

  • DES 不安全,至少使用 3DES(或正式的 TDEA);
  • ECB 模式不安全,请使用 CBC(确实使用 IV);
  • ECB模式不使用IV;
  • 对于客户端/服务器身份验证,您需要注意填充 oracle 攻击。
于 2012-09-08T12:09:11.933 回答
0

事实证明,我正在做的加密/解密没有任何问题。而是问题在于 PHP 中的 urldecode() 没有将 '%2B' 解码为 '+' (而是解码为 ' ')。我在 PHP 中从 urldecode() 切换到 rawurldecode() ,现在一切正常!

于 2012-09-08T19:30:01.740 回答