iPhone 3Des加密匹配Java和.NET密钥问题,SecretKeySpec?

时间:2010-08-09 19:26:31

标签: java .net iphone encryption 3des

我正在尝试使用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同行的结果相匹配的解决方案吗?

1 个答案:

答案 0 :(得分:1)

我明白了。在md5之后生成的密钥是32字节。从阅读其他帖子,似乎kCCKeySize3DES只有24个字节。如果我把一个24字节或更少的密钥(没有md5),这似乎完美。