我有以下方法,我想将其移植到基于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(...)
所需的参数。
答案 0 :(得分:0)
我通过实施附加的替换方法解决了这个问题。再次感谢所有有用和鼓舞人心的评论。
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];
}