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

发布于 2024-09-13 05:00:13 字数 3538 浏览 4 评论 0原文

我正在尝试在 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 对应项的结果?

I'm trying do some encrypt something using 3des on the iphone that must match the results from java and .NET.

the code i have is:

+ (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;

}

This code successfully encrypts and decrypts a string. As you can see, it uses md5 on the key. However, it does not match the results from .NET and java.

The java code from the java developer looks like:

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"));
}

Unfortunately I'm not too familiar with java encryption. I did notice that after using md5 on the KEY it creates a SecretKey with the method SecretKeySpec. My Java developer told me that he needed to create a secretkey using the byte array of the key so that it could match the .NET key.

Can anyone explain this better to me and help me with a solution to match the results of the .NET and java counterparts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜柠檬 2024-09-20 05:00:13

我想通了。 md5后生成的密钥是32字节。从阅读其他帖子来看,kCCKeySize3DES似乎只有24字节。如果我输入一个 24 字节或更少的密钥(无 md5),这似乎可以完美工作。

I figured it out. The key that is generated after i md5 it is 32 bytes. From reading other posts, it seems that kCCKeySize3DES is only 24 bytes. If i put a key that is 24 bytes or less (no md5) this seems to work perfectly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文