使用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
相关产品推荐
相关产品推荐

