2

我正在尝试在 iphone 上使用 3des 对某些内容进行加密,这些内容必须与 java 和 .NET 的结果相匹配。

我的代码是:

+ (NSString*) doCipher:(NSString*)plainText:(CCOperation)encryptOrDecrypt {

const void *vplainText;
size_t plainTextBufferSize;

if (encryptOrDecrypt == kCCDecrypt)
{
    NSData *EncryptData = [NSData dataWithBase64EncodedString:plainText];
    plainTextBufferSize = [EncryptData length];
    vplainText = [EncryptData bytes];
}
else
{
    NSData *tempData = [plainText dataUsingEncoding:NSASCIIStringEncoding];
    plainTextBufferSize = [tempData length];
    vplainText =  [tempData bytes];
}

CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
//  uint8_t ivkCCBlockSize3DES;

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

NSString *key = [NSString MD5:@"HSDNIFFU"];

NSData *_keyData = [key dataUsingEncoding:NSASCIIStringEncoding];

NSLog(@"key byte is %s", [_keyData bytes]);

// Initialization vector; dummy in this case 0's.
uint8_t iv[kCCBlockSize3DES];
memset((void *) iv, 0x0, (size_t) sizeof(iv));

ccStatus = CCCrypt(encryptOrDecrypt,
                   kCCAlgorithm3DES,
                   kCCOptionPKCS7Padding,
                   (const void *)[_keyData bytes], //"123456789012345678901234", //key
                   kCCKeySize3DES,
                   iv,  //iv,
                   vplainText,  //plainText,
                   plainTextBufferSize,
                   (void *)bufferPtr,
                   bufferPtrSize,
                   &movedBytes);

//if (ccStatus == kCCSuccess) NSLog(@"SUCCESS");
/*else*/ if (ccStatus == kCCParamError) return @"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED";

NSString *result;

if (encryptOrDecrypt == kCCDecrypt)
{

//  result = [[NSString alloc] initWithData: [NSData dataWithBytes:(const void *)bufferPtr length:[(NSUInteger)movedBytes] encoding:NSASCIIStringEncoding]];
    result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSASCIIStringEncoding] autorelease];
}
else
{
    NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
    NSLog(@"data is: %@", myData);
    result = [myData base64Encoding];
}
return result;

}

此代码成功地加密和解密了一个字符串。如您所见,它在密钥上使用 md5。但是,它与 .NET 和 java 的结果不匹配。

来自 java 开发人员的 java 代码如下所示:

public static byte[] encryptTripleDES(String message) throws Exception {
    final MessageDigest md = MessageDigest.getInstance("md5");
    final byte[] digestOfPassword = md.digest("--KEY--".getBytes("utf-8"));
    final SecretKey key = new SecretKeySpec(digestOfPassword, "DESede");
    final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
    final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, key, iv);
    return cipher.doFinal(message.getBytes("utf-8"));
}

不幸的是,我对 java 加密不太熟悉。我确实注意到在 KEY 上使用 md5 后,它使用 SecretKeySpec 方法创建了一个 SecretKey。我的 Java 开发人员告诉我,他需要使用密钥的字节数组创建一个密钥,以便它可以匹配 .NET 密钥。

谁能更好地向我解释这一点,并帮助我找到与 .NET 和 java 对应的结果相匹配的解决方案?

4

1 回答 1

1

我想到了。在 i md5 之后生成的密钥是 32 字节。从阅读其他帖子来看,kCCKeySize3DES 似乎只有 24 个字节。如果我放一个 24 字节或更少的密钥(没有 md5),这似乎工作得很好。

于 2010-08-09T22:35:22.993 回答