Дублирование Java-шифрования в Objective C - PullRequest
0 голосов
/ 29 августа 2011

Это продолжение этого вопроса, PBEWithMD5AndDES Шифрование в iOS , так как было предложено начать новые вопросы с другим подходом.

Что мне в основном нужно сделать, это продублировать некоторое шифрование, которое происходит в приложении для Android, в приложении для iOS. У меня работает какое-то шифрование, но, как говорится в предыдущем вопросе, зашифрованное значение несовместимо. Мне нужно, чтобы зашифрованное значение на стороне iOS было таким же, как зашифрованное значение на стороне Android, потому что они будут обмениваться этими данными. Я включаю функцию Java, а также целевой класс. Обе стороны гибки, я просто плохо знаю алгоритмы шифрования.

Вот функция Java.

public DesEncrypter(String passPhrase) {
try {
    // Create the key
    KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
    SecretKey key = SecretKeyFactory.getInstance(
        "PBEWithMD5AndDES").generateSecret(keySpec);
    ecipher = Cipher.getInstance(key.getAlgorithm());
    dcipher = Cipher.getInstance(key.getAlgorithm());

    // Prepare the parameter to the ciphers
    AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);

    // Create the ciphers
    ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
    dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (java.security.InvalidAlgorithmParameterException e) {
} catch (java.security.spec.InvalidKeySpecException e) {
} catch (javax.crypto.NoSuchPaddingException e) {
} catch (java.security.NoSuchAlgorithmException e) {
} catch (java.security.InvalidKeyException e) {
}

}

Вот объективный класс c.

@implementation CryptoHelper

#pragma mark -
#pragma mark Init Methods
- (id)init
{
    if(self = [super init])
    {

    }
    return self;
}

#pragma mark -
#pragma mark String Specific Methods

/** 
 *  Encrypts a string for social blast service. 
 *  
 *  @param  plainString The string to encrypt;
 *
 *  @return NSString    The encrypted string. 
 */
- (NSString *)encryptString: (NSString *) plainString{

    // Convert string to data and encrypt
    NSData *data = [self encryptPBEWithMD5AndDESData:[plainString dataUsingEncoding:NSUTF8StringEncoding] password:@"1111"];



    // Get encrypted string from data
    return [data base64EncodingWithLineLength:1024];

}


/** 
 *  Descrypts a string from social blast service. 
 *  
 *  @param  plainString The string to decrypt;
 *
 *  @return NSString    The decrypted string. 
 */
- (NSString *)decryptString: (NSString *) encryptedString{

    // decrypt the data
    NSData * data = [self decryptPBEWithMD5AndDESData:[NSData dataWithBase64EncodedString:encryptedString] password:@"1111"];

    // extract and return string
    return [NSString stringWithUTF8String:[data bytes]];

}


#pragma mark -
#pragma mark Crypto Methods

- (NSData *)encryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password {
    return [self encodePBEWithMD5AndDESData:inData password:password direction:1];
}

- (NSData *)decryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password {
    return [self encodePBEWithMD5AndDESData:inData password:password direction:0];
}

- (NSData *)encodePBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password direction:(int)direction
{
    NSLog(@"helper data = %@", inData);

    static const char gSalt[] =
    {
        (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA,
        (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA,
        (unsigned char)0x00
    };

    unsigned char *salt = (unsigned char *)gSalt;
    int saltLen = strlen(gSalt);
    int iterations = 15;

    EVP_CIPHER_CTX cipherCtx;


    unsigned char *mResults; // allocated storage of results
    int mResultsLen = 0;

    const char *cPassword = [password UTF8String];

    unsigned char *mData = (unsigned char *)[inData bytes];
    int mDataLen = [inData length];


    SSLeay_add_all_algorithms();
    X509_ALGOR *algorithm = PKCS5_pbe_set(NID_pbeWithMD5AndDES_CBC,
                                          iterations, salt, saltLen);



    memset(&cipherCtx, 0, sizeof(cipherCtx));

    if (algorithm != NULL)
    {
        EVP_CIPHER_CTX_init(&(cipherCtx));



        if (EVP_PBE_CipherInit(algorithm->algorithm, cPassword, strlen(cPassword),
                               algorithm->parameter, &(cipherCtx), direction))
        {

            EVP_CIPHER_CTX_set_padding(&cipherCtx, 1);

            int blockSize = EVP_CIPHER_CTX_block_size(&cipherCtx);
            int allocLen = mDataLen + blockSize + 1; // plus 1 for null terminator on decrypt
            mResults = (unsigned char *)OPENSSL_malloc(allocLen);


            unsigned char *in_bytes = mData;
            int inLen = mDataLen;
            unsigned char *out_bytes = mResults;
            int outLen = 0;



            int outLenPart1 = 0;
            if (EVP_CipherUpdate(&(cipherCtx), out_bytes, &outLenPart1, in_bytes, inLen))
            {
                out_bytes += outLenPart1;
                int outLenPart2 = 0;
                if (EVP_CipherFinal(&(cipherCtx), out_bytes, &outLenPart2))
                {
                    outLen += outLenPart1 + outLenPart2;
                    mResults[outLen] = 0;
                    mResultsLen = outLen;
                }
            } else {
                unsigned long err = ERR_get_error();

                ERR_load_crypto_strings();
                ERR_load_ERR_strings();
                char errbuff[256];
                errbuff[0] = 0;
                ERR_error_string_n(err, errbuff, sizeof(errbuff));
                NSLog(@"OpenSLL ERROR:\n\tlib:%s\n\tfunction:%s\n\treason:%s\n",
                      ERR_lib_error_string(err),
                      ERR_func_error_string(err),
                      ERR_reason_error_string(err));
                ERR_free_strings();
            }


            NSData *encryptedData = [NSData dataWithBytes:mResults length:mResultsLen]; //(NSData *)encr_buf;


            //NSLog(@"encryption result: %@\n", [encryptedData base64EncodingWithLineLength:1024]);

            EVP_cleanup();

            return encryptedData;
        }
    }
    EVP_cleanup();
    return nil;

}

@end

Я использую статическую библиотеку openssl для ios.

Спасибо, Brandon

1 Ответ

2 голосов
/ 29 августа 2011

Для правильной работы шифрования все должно быть одинаково на обоих концах.Тот же режим, та же клавиша, тот же IV и тот же отступ.Вы должны проверить каждый из них.Не полагайтесь на режим по умолчанию, но явно указывайте CBC (или CTR) на обоих концах.После генерации ключа напечатайте его в шестнадцатеричном виде на обоих концах, чтобы убедиться, что он идентичен.Напечатайте IV в шестнадцатеричном виде на обоих концах, чтобы проверить.Не полагайтесь на значения по умолчанию, но явно указывайте заполнение (PKCS5 или PKCS7) на обоих концах.

Я также видел проблемы с зашифрованным текстом, где он преобразуется в строку в одну кодировку символов, но преобразуется обратно в байтыкак будто это было в другой кодировке символов.Убедитесь, что вы используете одну и ту же кодировку символов на обоих концах.

Как только вы определили, где происходят несоответствия, вы можете исправить их.

На заметке сторон, я заметил, что вы используетеDES.Это теперь устарело и должно использоваться только для обратной совместимости.Используйте AES для всех новых приложений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...