【问题标题】:How to port OpenSSL-based DES decryption method to CommonCrypto?如何将基于 OpenSSL 的 DES 解密方法移植到 CommonCrypto?
【发布时间】:2014-10-09 23:19:41
【问题描述】:

我有以下方法,我想将其移植到基于 CommonCrypto 的方法,但我完全卡住了。非常感谢任何帮助。

- (NSString*) decryptCiscoPassword:(NSString*) encPassword
{
    NSUInteger i, k = 0;
    NSData *rawData = nil;
    int rawInt, rawDataLength = [encPassword length] >> 1;
    const char *encString = [encPassword cStringUsingEncoding:NSUTF8StringEncoding];
    const char *tmpString;
    unsigned char *rawDataBytes = (unsigned char*) malloc(rawDataLength*sizeof(unsigned char));

    for(i = 0; i < [encPassword length]; i = i+2)
    {
        tmpString = &encString[i];
        sscanf(tmpString,"%2x",&rawInt);
        rawDataBytes[k++] = (unsigned char) rawInt;
    }
    rawData = [NSData dataWithBytesNoCopy:rawDataBytes length:rawDataLength freeWhenDone:YES];

    /* now let's start the decryption */

    NSString *returnString = nil;

    /* --- calculate 3DES-Key --- */
    DES_cblock desKey1, desKey2, desKey3;

    unsigned char tempHash[20];
    [rawData getBytes:tempHash length:20];
    tempHash[19]++;

    unsigned char hashV1[20];
    CC_SHA1(tempHash,20,hashV1);

    unsigned char hashV2[20];
    tempHash[19] += 2;
    CC_SHA1(tempHash,20,hashV2);

    memcpy(&desKey1, hashV1, 8);
    memcpy(&desKey2, &hashV1[8], 8);
    memcpy(&desKey3, &hashV1[16], 4);
    memcpy(&desKey3[4], hashV2, 4);

    /* --- Decryption (8 byte blockSize, 24 byte Keylength) --- */
    DES_cblock iv;
    [rawData getBytes:iv length:8];
    NSInteger length = [rawData length];
    unsigned char *rawDataChar = (unsigned char*) malloc(length * sizeof(unsigned char));
    [rawData getBytes:rawDataChar length:length];

    NSInteger blockCount = (length - 40) / 8;
    if(blockCount < 1)
    {
        free(rawDataChar);
        return nil; // encPassword is no valid DES-encrypted password!
    }
    NSUInteger pwLength = blockCount*8;
    char* output = (char*) malloc(pwLength*sizeof(char));

    DES_key_schedule key_schedule1, key_schedule2, key_schedule3;

    DES_set_key_unchecked(&desKey1, &key_schedule1);     // generate key_schedule
    DES_set_key_unchecked(&desKey2, &key_schedule2);     // generate key_schedule
    DES_set_key_unchecked(&desKey3, &key_schedule3);     // generate key_schedule
    DES_ede3_cbc_encrypt((unsigned char*)&rawDataChar[40],(unsigned char*)output, pwLength,&key_schedule1,&key_schedule2,&key_schedule3,&iv,0);

    unsigned char len = output[pwLength-1];

    /* create null-terminated c-string */
    output[pwLength-len] = 0;

    /* rescue decrypted string */
    returnString = @(output);

    /* free allocated memory */
    free(rawDataChar);
    free(output);

    return returnString;

}

我已经找到了 CommonCrypto 函数

CCCryptorStatus CCCrypt(CCOperation op, CCAlgorithm alg, CCOptions options, const void *key, size_t keyLength, const void *iv, const void *dataIn, size_t dataInLength, void *dataOut, size_t dataOutAvailable, size_t *dataOutMoved);

但我不确定如何将我在原始方法中派生的 OpenSSL 参数移植到CCCrypt(...) 所需的参数。

【问题讨论】:

  • 您将需要查看 CommonCrypto API 的参数,查看每个参数是什么以及您需要什么,然后通过 OpenSSL API 查找对应的内容。这是一个非常具体的问题,所以我怀疑任何人都能够立即回答......
  • 好的。关于不清楚的参数在这里更具体:DES_ede3_cbc_encrypt 中的key_scheduleCCCryptkey 参数有什么区别?我怎么能从另一个那里得到一个?
  • 上面的代码看起来使用的是 DES3。只是为了确定——你是在 CCCrypt 中使用普通 DES 还是 DES3?
  • 我使用的是3DES,但更重要的问题是如何根据我掌握的信息生成key参数。
  • 我将不得不更详细地查看它并回复您...

标签: objective-c encryption openssl commoncrypto


【解决方案1】:

我通过实施附加的替换方法解决了这个任务。再次感谢所有有帮助和鼓舞人心的 cmets。

NSString* CSDecryptCiscoPassword(NSString* encPassword)
{
    // convert to C
    NSUInteger rawDataLength = [encPassword length] >> 1;
    const char *encString = [encPassword cStringUsingEncoding:NSUTF8StringEncoding];

    // convert hex to bytes
    NSUInteger k = 0;
    unsigned char rawDataBytes[rawDataLength];
    for(NSUInteger i = 0; i < [encPassword length]; i = i+2)
    {
        const char *tmpString = &encString[i];
        int rawInt;
        sscanf(tmpString,"%2x",&rawInt);
        rawDataBytes[k++] = (unsigned char) rawInt;
    }

    const char *h1  = (const char*)rawDataBytes;
    const char *h4  = (const char*)rawDataBytes + 20;
    const char *enc = (const char*)rawDataBytes + 40;

    unsigned char ht[20], h2[20], h3[20], key[24];
    const char *iv = h1;

    if (rawDataLength < 48)
        return nil;
    rawDataLength -= 40;

    memcpy(ht, h1, 20);

    ht[19]++;
    CC_SHA1(ht, 20, h2);

    ht[19] += 2;
    CC_SHA1(ht, 20, h3);

    memcpy(key, h2, 20);
    memcpy(key+20, h3, 4);

    CC_SHA1(enc, rawDataLength, ht);

    if (memcmp(h4, ht, 20) != 0)
        return nil;

    size_t outLength = 0;
    NSMutableData *outputData = [NSMutableData dataWithLength:(rawDataLength+kCCBlockSize3DES)];

    CCCryptorStatus result = CCCrypt(kCCDecrypt, // operation
                     kCCAlgorithm3DES, // Algorithm
                     0, // options
                     key, // key
                     24, // keylength
                     iv,// iv
                     enc, // dataIn
                     rawDataLength, // dataInLength,
                     outputData.mutableBytes, // dataOut
                     outputData.length, // dataOutAvailable
                     &outLength); // dataOutMoved

    NSString* outString = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding];

    return [outString autorelease];
}

【讨论】:

    猜你喜欢
    • 2011-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 2014-01-08
    • 1970-01-01
    • 2017-03-06
    • 2020-12-04
    相关资源
    最近更新 更多