0

我真的真的……真的需要帮助…………

-更新-

我需要帮助,因为与 iOS 3DES 函数相比,我的 java 函数给了我不同的结果。我发布了来自 ios 和 java 的代码;当指定明文为“tutor.1”且 MD5 密钥为“spO13+QLZCRAe93pIXMXLg==”(显然,MD5 对两者相同)时的结果。

JAVA 3DES(简短而简单)

public static String encrypt(String plaintext, String enctoken){

    if(enctoken == null)
        enctoken = "sfdjf48mdfdf3054";

    String encrypted = null; 

    byte[] plaintextByte = EncodingUtils.getBytes(plaintext,"UTF-8");

    byte[] hash = Connessione.md5(enctoken);

    Log.i("ENCRYPT", "MD5: "+Base64.encodeToString(hash, 0));

    try {
        Cipher cipher = Cipher.getInstance("DESEDE/ECB/PKCS5Padding");
        SecretKeySpec myKey = new SecretKeySpec(hash,"DESede");

        cipher.init(Cipher.ENCRYPT_MODE, myKey); 

        try {
            byte[] encryptedPlainText = cipher.doFinal(plaintextByte);

            encrypted = Base64.encodeToString(encryptedPlainText, 0);

            Log.i("ENCRYPT", "Pwd encrypted: "+encrypted);

            return encrypted;

        } catch (IllegalBlockSizeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }       

    return "";
}

结果:R4mXAaHcFxM=

IOS 3DES - 再次更新

// key value in parameters is MD5 value! It is the same for both version

+ (NSString *) encrypt:(NSString *) dataToEncrypt withKey:(NSString*) key{    


NSData *data = [dataToEncrypt dataUsingEncoding:NSUTF8StringEncoding];
NSData *mData = [key dataUsingEncoding:NSUTF8StringEncoding];

CCCryptorStatus ccStatus = kCCSuccess;


// Begin to calculate bytesNeeded....
size_t bytesNeeded = 0;

ccStatus = CCCrypt(kCCEncrypt,
                   kCCAlgorithm3DES,
                   kCCOptionECBMode | kCCOptionPKCS7Padding,
                   [mData bytes],
                   [mData length],
                   nil,
                   [data bytes],
                   [data length],
                   NULL,
                   0,
                   &bytesNeeded);

if(kCCBufferTooSmall != ccStatus){

    NSLog(@"Here it must return BUFFER TOO SMALL !!");
    return nil;
}

// .....End
// Now i do the real Crypting

char* cypherBytes = malloc(bytesNeeded);
size_t bufferLength = bytesNeeded;

if(NULL == cypherBytes)
    NSLog(@"cypherBytes NULL");

ccStatus = CCCrypt(kCCEncrypt,
                   kCCAlgorithm3DES,
                   kCCOptionECBMode | kCCOptionPKCS7Padding,
                   [mData bytes],
                   [mData length],
                   nil,
                   [data bytes],
                   [data length],
                   cypherBytes,
                   bufferLength,
                   &bytesNeeded);

if(kCCSuccess != ccStatus){
    NSLog(@"kCCSuccess NO!");
    return nil;
}

return [Base64 encode:[NSData dataWithBytes:cypherBytes length:bufferLength]]; 

}

结果:YBAva5J2khY=

我需要 iOS 版本返回与 Java 版本相同的结果。

我在这里找到了 Base64 类:http ://www.imthi.com/blog/programming/iphone-sdk-base64-encode-decode.php

我做错了什么?

感谢您的帮助和时间

4

2 回答 2

0

Ok, I started off easier, using DES encryption. Also, I'm skipping the Base64 and the hashing on the key - all of these are easily added once you're sure that the encryption is working properly, and they can be added one at a time.

Here's the iOS code:

#import <UIKit/UIKit.h>
#import <CommonCrypto/CommonCrypto.h>
#import <CommonCrypto/CommonCryptor.h>

int main(int argc, char *argv[])
{
    @autoreleasepool {


            BOOL encryptOrDecrypt = kCCEncrypt;
            NSString *plainText = @"abcdefghijklmnop";
            NSString *key = @"01234567";

            const void *vplainText;
            size_t plainTextBufferSize;

            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;

            bufferPtrSize = [plainText length];
            if (bufferPtrSize % 8) {
                bufferPtrSize += 8 - (bufferPtrSize % 8);
            }

//            bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
            bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t) + 1);   // To null-terminate a string if req'd
            memset((void *)bufferPtr, 0x0, bufferPtrSize+1);

            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,
                                   kCCAlgorithmDES,
                                   kCCOptionECBMode, //kCCOptionPKCS7Padding | kCCOptionECBMode,
                                   (const void *)[_keyData bytes], //key
                                   kCCKeySizeDES,
                                   nil,  //iv,
                                   vplainText,  //plainText,
                                   plainTextBufferSize,
                                   (void *)bufferPtr,
                                   bufferPtrSize,
                                   &movedBytes);

            //if (ccStatus == kCCSuccess) NSLog(@"SUCCESS");
            /*else*/
            switch (ccStatus) {
                case kCCParamError:
                    NSLog(@"PARAM ERROR");
                    break;
                case kCCBufferTooSmall:
                    NSLog(@"BUFFER TOO SMALL");
                    break;
                case kCCMemoryFailure:
                    NSLog(@"MEMORY FAILURE");
                    break;
                case kCCAlignmentError:
                    NSLog(@"ALIGNMENT ERROR");
                    break;
                case kCCDecodeError:
                    NSLog(@"DECODE ERROR");
                    break;
                case kCCUnimplemented:
                    NSLog(@"UNIMPLEMENTED");
                    break;
                default:
                    NSLog(@"encrypt seems to have worked");
                    break;
            }

            for (size_t i=0; i<movedBytes; i++) {
                printf("%02x ", (int) bufferPtr[i]);
            }
            printf("\n");

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([FAAppDelegate class]));
    }
}

And here's the Java code:

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;


public class DesRun {
    /**
     * @param args
     */
    public static void main(String[] args) {
        String theKey = "01234567";
        String message = "abcdefghijklmnop";
        Cipher ecipher, dcipher;
         try {
            // generate secret key using DES algorithm
             SecretKeySpec key = new SecretKeySpec(theKey.getBytes("UTF-8"), "DES");

                 ecipher = Cipher.getInstance("DES");
                 dcipher = Cipher.getInstance("DES");

                 // initialize the ciphers with the given key
                 ecipher.init(Cipher.ENCRYPT_MODE, key);
                 dcipher.init(Cipher.DECRYPT_MODE, key);

                 byte[] encrypted = ecipher.doFinal(message.getBytes("UTF-8"));
                 System.out.println(DatatypeConverter.printHexBinary(encrypted));
                 String decrypted = new String(dcipher.doFinal(encrypted), "UTF-8");

                 System.out.println("Decrypted: " + decrypted);

             }
             catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

    }
}

Both print out the hex bytes of the encrypted data, and they agree.

Now it should be (relatively) easy to move to 3DES.

Only once you've got 3DES agreeing on both iOS and Java would I start to add hashing on the keys.

于 2012-10-08T08:46:50.263 回答
0

Error found. keydata encoding was different

于 2012-11-19T17:24:00.690 回答