如何在iOS的AES加密中添加盐并使用目标c对其解密 [英] How to add salt to AES Encryption in iOS and decrypting it using objective c

查看:218
本文介绍了如何在iOS的AES加密中添加盐并使用目标c对其解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过在iOS中使用目标c将IV附加到AES加密/解密代码中,并能够对其进行解密和加密.现在,我正在尝试将盐添加到AES加密中,但是很不幸,它对我不起作用.这是代码:我还使用Android盐生成代码进行了编辑,目的只是为了检查我的盐生成在iOS中是否有效

I have appended the IV to the AES Encryption/decryption code by using objective c in iOS and able to decrypt and encrypt the same. Right now I am trying to add the salt to the AES Encryption but unfortunately its not working for me. Here is the code: I have also edited with Android salt generation code for just to check whether my salt generation is valid or not in iOS

加密代码:

    + (NSData*)encryptData:(NSData*)data key:(NSData*)key error:(NSError **)error;
{
    NSData *salt = [self randomDataOfLength:16];
    if (key.length != 16 && key.length != 24 && key.length != 32) {
        *error = [NSError errorWithDomain:@"keyLengthError" code:-1 userInfo:nil];
        return nil;
    }

    CCCryptorStatus ccStatus   = kCCSuccess;
    int             ivLength   = kCCBlockSizeAES128;
    size_t          cryptBytes = 0;
    NSMutableData  *dataOut     = [NSMutableData dataWithLength:ivLength + data.length + kCCBlockSizeAES128];

    int status = SecRandomCopyBytes(kSecRandomDefault, ivLength, dataOut.mutableBytes);
    NSLog(@"Data Out String Encrypt%@", dataOut);
    NSLog(@"Status ID Engrypt%d", status);
    if (status != 0) {
        *error = [NSError errorWithDomain:@"ivError" code:status userInfo:nil];
        return nil;
    }
    ccStatus = CCCrypt(kCCEncrypt,
                       kCCAlgorithmAES,
                       kCCOptionPKCS7Padding,
                       key.bytes,
                       key.length,
                       dataOut.bytes,
                       data.bytes,
                       data.length,
                       dataOut.mutableBytes + ivLength, dataOut.length,
                       &cryptBytes);

    if (ccStatus == kCCSuccess) {
        dataOut.length = cryptBytes + ivLength;
    }
    else {
        if (error) {
            *error = [NSError errorWithDomain:@"kEncryptionError" code:ccStatus userInfo:nil];
        }
        dataOut = nil;
    }

    return dataOut;
}

解密代码:

+ (NSData*)decryptData:(NSData*)data key:(NSData*)key error:(NSError **)error;
{
    if (key.length != 16 && key.length != 24 && key.length != 32) {
        *error = [NSError errorWithDomain:@"keyLengthError" code:-1 userInfo:nil];
        return nil;
    }

    
    CCCryptorStatus ccStatus   = kCCSuccess;
    int             ivLength   = kCCBlockSizeAES128;
    size_t          clearBytes = 0;
    NSMutableData *dataOut     = [NSMutableData dataWithLength:data.length - ivLength];
    
    NSLog(@"Data Out String Decrypt%@", dataOut);

    ccStatus = CCCrypt(kCCDecrypt,
                       kCCAlgorithmAES,
                       kCCOptionPKCS7Padding,
                       key.bytes,
                       key.length,
                       data.bytes,
                       data.bytes + ivLength,
                       data.length - ivLength,
                       dataOut.mutableBytes,
                       dataOut.length,
                       &clearBytes);

    if (ccStatus == kCCSuccess) {
        dataOut.length = clearBytes;
    }
    else {
        if (error) {
            *error = [NSError errorWithDomain:@"kEncryptionError" code:ccStatus userInfo:nil];
        }
        dataOut = nil;
    }

    return dataOut;
}

生成随机盐和算法.

+ (NSData *)randomDataOfLength:(size_t)length {
  NSMutableData *data = [NSMutableData dataWithLength:length];
  
  int result = SecRandomCopyBytes(kSecRandomDefault,
                                  length,
                                  data.mutableBytes);
  NSAssert(result == 0, @"Unable to generate random bytes: %d",
           errno);
  
  return data;
}

// Replace this with a 10,000 hash calls if you don't have CCKeyDerivationPBKDF
+ (NSData *)AESKeyForPassword:(NSString *)password
                         salt:(NSData *)salt {
  NSMutableData *
  derivedKey = [NSMutableData dataWithLength:32];
  
  int
  result = CCKeyDerivationPBKDF(kCCPBKDF2,            // algorithm
                                password.UTF8String,  // password
                                [password lengthOfBytesUsingEncoding:NSUTF8StringEncoding],  // passwordLength
                                salt.bytes,           // salt
                                salt.length,          // saltLen
                                kCCPRFHmacAlgSHA1,    // PRF
                                10000,         // rounds
                                derivedKey.mutableBytes, // derivedKey
                                derivedKey.length); // derivedKeyLen
  
  // Do not log password here
  NSAssert(result == kCCSuccess,
           @"Unable to create AES key for password: %d", result);
  
  return derivedKey;
}

我已经基于链接在此处输入链接描述,但是不幸的是,我得到了解密输出为nil

I have done all these based on the link enter link description here But unfortunately I am getting the output of decryption as nil

请指出哪里做错了吗?

我已经从Encrypt方法中删除了Salt生成代码.我将代码移到了 ViewController.m ,这是代码:

I have removed the Salt generation code from the Encrypt method . I moved the code to the ViewController.m here is the code:

NSString *myScretString = @"My encryption string";
NSData *salt = [FBEncryptorAES randomDataOfLength:16];
NSData *key1 = [FBEncryptorAES AESKeyForPassword:@"E8E033BC691W5F092BB5909933636552" salt:salt];
NSData* encryptedData = [FBEncryptorAES encryptData:[myScretString dataUsingEncoding:NSUTF8StringEncoding]
                                                key:key1
                                              error:&error];

NSLog(@"encryptedWithDynamicIV: %@", [encryptedData base64EncodedStringWithOptions:0]);

NSData* decryptedData = [FBEncryptorAES decryptData:encryptedData
                                                    key: key1
                                                  error:&error];
    NSLog(@"decryptedWithDynamicIV: %@", [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding]);

这是Android SALT生成代码:

Here is the Android SALT generation code :

private static final String ALGORITHM = "AES";
        private static final String MODE = "AES/CBC/PKCS5Padding";
        private static final String KEY = "5909E8E0335F092BBBC699336365521W";
 
byte[] salt = generateSalt();
               SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
               KeySpec spec = new PBEKeySpec(KEY.toCharArray(), salt, 65536, 256);
               SecretKey tmp = factory.generateSecret(spec);
               SecretKeySpec secretKeySpec = new SecretKeySpec(tmp.getEncoded(), ALGORITHM);

推荐答案

您正在扩展加密密钥,但没有扩展解密密钥.解密代码从不调用AESKeyForPassword,而且我看不到您将盐存储到任何地方以将其发送给解密器的方式(将IV发送给解密器的方式).您不能仅将PBKDF2应用于一侧.这给您完全不同的键.

You're stretching your encryption key, but you're not stretching your decryption key. The decryption code never calls AESKeyForPassword, and I don't see anywhere that you store the salt to send it to the decryptor (the way you send the IV to the decryptor). You can't just apply PBKDF2 to one side. That gives you completely different keys.

这篇关于如何在iOS的AES加密中添加盐并使用目标c对其解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆