You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用RNCryptor解密OC加密数据时抛出unknownHeader错误

问题:Swift解密Objective-C生成的RNCryptor加密文件时出现unknownHeader错误

我曾在Objective-C项目中使用RNCryptor对plist数据文件进行加密和解密。现在用Swift重构项目,解密原Objective-C生成的plist数据时,始终抛出“Decryption error: unknownHeader”错误。使用了相同的App标识符,能访问Documents目录中的同一plist文件。

Objective-C 加密代码

- (void)savePasswordlistItems {
    NSMutableData *data = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:items forKey:@"MyKey"];
    [archiver finishEncoding];
   
    NSError *error;
    NSData *encryptedData = [RNEncryptor encryptData:data
                                        withSettings:kRNCryptorAES256Settings
                                            password:MY_SECRET_KEY
                                               error:&error];
    [encryptedData writeToFile:[self dataFilePath] atomically:YES];
}

Objective-C 解密代码

- (void)loadPasswordlistItems {
    if ([[NSFileManager defaultManager] fileExistsAtPath:path])
    {
        NSData *data = [[NSData alloc] initWithContentsOfFile:path];
        
        NSError *error;
        NSData *decryptedData = [RNDecryptor decryptData:data
                                            withPassword:MY_SECRET_KEY
                                                   error:&error];

        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData: decryptedData];
        items = [unarchiver decodeObjectForKey:@"MyKey"];
        [unarchiver finishDecoding];
    }
    else
    {
        items = [[NSMutableArray alloc] initWithCapacity:20];
    }
}

Swift 解密代码

func loadPasswordlistItems() {
        let path = dataFilePath()
        if FileManager.default.fileExists(atPath: path) {
            do {
                let data = try Data(contentsOf: URL(fileURLWithPath: path))
                
                do {
                    let decryptedData = try RNCryptor.decrypt(data: data, withPassword: Constants.MY_SECRET_KEY)
                    let unarchiver = try NSKeyedUnarchiver(forReadingFrom: decryptedData)
                    items = (unarchiver.decodeObject(forKey: "MyKey") as! NSMutableArray)
                    unarchiver.finishDecoding()                    
                } catch {
                    // Handle decryption error
                    print("Decryption error: \(error)")
                }
            } catch {
                // Handle reading data from file error
                print("Error reading data from file: \(error)")
            }
        } else {
            items = []
        }
    }

Swift 加密代码(未测试)

func savePasswordlistItems() {
        let data = NSMutableData()
        let archiver = NSKeyedArchiver(forWritingWith: data)
        archiver.encode(items, forKey: "MyKey")
        archiver.finishEncoding()
                
        let encryptedFile = RNCryptor.encrypt(data: data as Data, withPassword: Constants.MY_SECRET_KEY)
        do {
            try encryptedFile.write(to: URL(fileURLWithPath: dataFilePath()), options: .atomic)
        } catch {
            print(error)
        }
    }

问题原因及解决方案

出现unknownHeader错误的核心原因是Objective-C代码使用kRNCryptorAES256Settings(对应RNCryptor v2格式)加密,但Swift代码解密时默认使用v3格式,版本不兼容导致无法识别加密头部。

具体解决方法:

  • 指定解密版本为v2:修改Swift解密代码,在解密时明确指定版本参数,匹配Objective-C的加密格式:
    let decryptedData = try RNCryptor.decrypt(data: data, withPassword: Constants.MY_SECRET_KEY, version: .v2)
    
  • 验证密码一致性:确保Constants.MY_SECRET_KEY和Objective-C中的MY_SECRET_KEY完全一致,包括大小写、特殊字符,任何细微差异都会导致解密失败。
  • (可选)统一加密格式:如果后续希望使用最新的v3格式,需修改Objective-C加密代码改用kRNCryptorAES256v3Settings,但此操作会导致旧的v2加密文件无法解密,需做版本兼容处理。

内容的提问来源于stack exchange,提问作者Kalaichelvan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 14:22:19