标签: nssecurecoding

何时使用NSSecureCoding

我正在学习NSSecureCodingApple在iOS 6中引入的协议.

根据我的理解,到目前为止,只要一个类对自身的实例进行编码/解码,就应该使用它,以防止替换攻击.

我想知道在其他情况下使用它是否合适.

具体来说,如果一个类NSCoding通过编码/解码其实例变量来符合,而不是整个实例,那么它仍然是可行的NSSecureCoding吗?


编辑

假设我有一个实现NSCoding如下的类

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.aString forKey:@"aMeaningfulString"];
}

- (id)initWithCoder:(NSCoder *)decoder {
    if((self = [super init])) {
        self.aString = [decoder decodeObjectForKey:@"aMeaningfulString"];
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

并且还假设没有涉及XPC.此类的实例将存储在磁盘上的plist中.

在安全方面,使用是否有任何好处,-decodeObjectOfClass:forKey:而不是 -decodeObjectForKey:

security objective-c nscoding ios nssecurecoding

25
推荐指数
1
解决办法
9029
查看次数

UNMutableNotificationContent与userinfo中的自定义对象

我想在UNMutableNotificationContent的userinfo中使用cutom对象,但它不起作用.当我在userinfo中放置自定义对象时,不会触发通知.

使用此代码,会触发通知:

let content = UNMutableNotificationContent()
content.title = "title"
content.body = "body"
content.categoryIdentifier = "alarmNotificationCategory"
content.sound = UNNotificationSound.default()
content.userInfo = ["myKey": "myValue"] as [String : Any]


let request = UNNotificationRequest(identifier: "alarmNotification", content: content, trigger: nil)
UNUserNotificationCenter.current().add(request) { error in
    UNUserNotificationCenter.current().delegate = self
    if error != nil {
        print(error!)
    }
}
Run Code Online (Sandbox Code Playgroud)

使用以下内容,不会发出错误,但不会触发通知:

let content = UNMutableNotificationContent()
content.title = "title"
content.body = "body"
content.categoryIdentifier = "alarmNotificationCategory"
content.sound = UNNotificationSound.default()
content.userInfo = ["myKey": TestClass(progress: 2)] as [String : Any]


let request = UNNotificationRequest(identifier: …
Run Code Online (Sandbox Code Playgroud)

notifications userinfo ios nssecurecoding swift

11
推荐指数
1
解决办法
3087
查看次数

将 NSSecureUnarchiveFromDataTransformer 用于 Transformable 属性时崩溃

在 iOS 12 中,Apple 引入了NSSecureUnarchiveFromDataTransformerName用于 CoreData 模型实体的可转换属性。我曾经将 Transformer Name 字段保持为空,它隐式使用了NSKeyedUnarchiveFromDataTransformerName. 这个转换器现在已被弃用,将来保持该字段为空将意味着NSSecureUnarchiveFromDataTransformerName取而代之。

在 iOS 13 中,如果该字段为空,您现在会收到一个运行时警告,告诉您上述内容。我在任何地方都找不到关于此的任何文档,我得到的唯一参考是 WWDC 2018 核心数据最佳实践演讲,其中简要提到了我刚才所说的内容。

现在我有一个带有实体的模型,该实体直接将HTTPURLResponse对象存储在 Transformable 属性中。它符合NSSecureCoding,我在运行时检查supportsSecureCodingtrue

NSSecureUnarchiveFromDataTransformerNameTransformer Name 的设置崩溃并显示以下消息:

Object of class NSHTTPURLResponse is not among allowed top level class list (
    NSArray,
    NSDictionary,
    NSSet,
    NSString,
    NSNumber,
    NSDate,
    NSData,
    NSURL,
    NSUUID,
    NSNull
) with userInfo of (null)
Run Code Online (Sandbox Code Playgroud)

所以听起来 Transformable 属性只能是这些顶级对象。

我尝试对安全转换器进行子类化并allowedTopLevelClasses按照文档的建议覆盖该属性:

@available(iOS 12.0, *)
public class NSSecureUnarchiveHTTPURLResponseFromDataTransformer: NSSecureUnarchiveFromDataTransformer …
Run Code Online (Sandbox Code Playgroud)

core-data ios nssecurecoding ios13

10
推荐指数
1
解决办法
2498
查看次数

使用NSSecureCoding强制执行类型

我决定使用NSSecureCodingNSCoding,但我无法让它工作.

我希望以下代码失败,因为我正在编码NSString但尝试解码NSNumber.但是,初始化对象时不会抛出异常.

+ (BOOL)supportsSecureCoding
{
    return YES;
}

- (instancetype)initWithCoder:(NSCoder *)coder
{
    // prints '1' as expected
    NSLog(@"%d", coder.requiresSecureCoding);

    // unexpectedly prints 'foo' (expecting crash)
    NSLog(@"%@", [coder decodeObjectOfClass:NSNumber.class forKey:@"bar"]);

    return [super init];
}

- (void)encodeWithCoder:(NSCoder *)coder
{
    [coder encodeObject:@"foo" forKey:@"bar"];
}
Run Code Online (Sandbox Code Playgroud)

这是我用来测试上面代码片段的代码:

MyClass *object = [[MyClass alloc] init];

NSMutableData *const data = [[NSMutableData alloc] init];
NSKeyedArchiver *const archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
archiver.requiresSecureCoding = YES;

[archiver encodeObject:object forKey:@"root"];
[archiver finishEncoding];

NSKeyedUnarchiver *const …
Run Code Online (Sandbox Code Playgroud)

cocoa objective-c nscoding ios nssecurecoding

9
推荐指数
1
解决办法
2806
查看次数

通过NSSecureCoding解码NSArray时的奇怪行为

我花了整个下午的时间撞到墙上,试图弄清楚为什么这门课的解码失败了.该类有一个属性,它是Foo对象的NSArray.Foo符合NSSecureCoding,我已成功编码并解码了该类.我在initWithCoder中收到错误:表示无法解码类Foo.通过一些实验,我发现我需要将[Foo类]添加到initWithCoder:为了使它工作.也许这会帮助那些遇到同样问题的人.我的问题是,为什么这是必要的?我没有发现在Apple的文档中这是必要的.

#import "Foo.h"

@interface MyClass : NSObject <NSSecureCoding>
@property (nonatomic) NSArray *bunchOfFoos;
@end

@implementation MyClass

static NSString *kKeyFoo = @"kKeyFoo";

+ (BOOL) supportsSecureCoding
{
    return YES;
}

- (void) encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:self.bunchOfFoos forKey:kKeyFoo];
}

- (id) initWithCoder:(NSCoder *)decoder
{
    if (self = [super init])
    {
        [Foo class]; // Without this, decoding fails
        _bunchOfFoos = [decoder decodeObjectOfClass:[NSArray class] forKey:kKeyFoo];
    }
    return self;
}

@end
Run Code Online (Sandbox Code Playgroud)

objective-c nscoding nsarray ios nssecurecoding

7
推荐指数
2
解决办法
1647
查看次数

如何将NSSecureCoding与id对象一起使用

我正在创建一个链表并使用容器对对象,下一个和以前的属性进行分组.像基金会收藏品一样,我希望它能够实施NSSecureCoding.这是宣言:

@interface ListContainer : NSObject <NSCopying, NSSecureCoding>

@property (readonly, nonatomic) id object;
@property (nonatomic) ListContainer * next;
@property (nonatomic) ListContainer * previous;

@end
Run Code Online (Sandbox Code Playgroud)

当实现该- initWithCoder:方法时,它让我觉得我不知道该对象使用什么类:

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];

    if (self) {

        _object = [aDecoder decodeObjectOfClass:<#(__unsafe_unretained Class)#> forKey:@"object"];

        BOOL nextIsNil = [aDecoder decodeBoolForKey:@"nextIsNil"];

        if (!nextIsNil) {

            // Decode next
            _next = [aDecoder decodeObjectOfClass:[ListContainer class] forKey:@"next"];

            if (_next == nil) {
                return nil;
            }

            // Link the nodes manually to prevent infinite recursion …
Run Code Online (Sandbox Code Playgroud)

objective-c nssecurecoding

7
推荐指数
1
解决办法
1330
查看次数

NSSecureCoding与自定义类的集合有问题

我在采用NSSecureCoding方面遇到了麻烦.我编码一个包含我的自定义类的对象的数组,它NSSecureCoding正确采用.当我解码它,传递类NSArray(它是我编码的对象的类)时,它会抛出异常.但是,当使用字符串数组执行完全相同的操作时,它可以正常工作.我没看到我的类和NSString之间有什么区别.

#import <Foundation/Foundation.h>

@interface Foo : NSObject <NSSecureCoding>
@end
@implementation Foo
- (id)initWithCoder:(NSCoder *)aDecoder {
  return [super init];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
}
+ (BOOL)supportsSecureCoding {
  return YES;
}
@end

int main() {
  @autoreleasepool {

    NSMutableData* data = [[NSMutableData alloc] init];
    NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:@[[Foo new]] forKey:@"foo"];
    [archiver encodeObject:@[@"bar"] forKey:@"bar"];
    [archiver finishEncoding];

    NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    unarchiver.requiresSecureCoding = YES;
    // throws exception: 'value for key 'NS.objects' was …
Run Code Online (Sandbox Code Playgroud)

objective-c nscoding nssecurecoding

6
推荐指数
2
解决办法
2932
查看次数

如何在Swift 3中使用NSSecureCoding解码字符串?

我目前正在尝试iOS 10 Beta并决定将我的Swift代码转换为Swift 3.到现在为止,我能够安全地解码一个String

coder.decodeObjectOfClass(NSString.self, forKey: CoderKeys.code) as! String
Run Code Online (Sandbox Code Playgroud)

转换到Swift 3后,Xcode给了我以下错误:

'decodeObjectOfClass(_:forKey:)' is unavailable in Swift: use generic 'decodeObjectClass(_:forKey:)'
Run Code Online (Sandbox Code Playgroud)

正如我所提到的,我正在使用NSSecureCoding,所以很遗憾decodeObject(forKey: String)不会这样做.这是测试版错误吗?我错过了什么?

xcode ios nssecurecoding swift3

4
推荐指数
1
解决办法
2469
查看次数

使用“优化速度”选项时,`supportsSecureCoding` 崩溃

我在创建使用 NSSecureCoding 及其子类的类时遇到问题。

class ClassA: NSObject, NSSecureCoding {
    public static var supportsSecureCoding: Bool { return true }
}

class ClassB: ClassA {
    public static var supportsSecureCoding: Bool { return true } // "Cannot override static var"
}
Run Code Online (Sandbox Code Playgroud)

我应该这样称呼,因为 NSObject.h 中的文档说,

此属性必须在所有允许安全编码的类上返回 YES。采用 NSSecureCoding 并覆盖 initWithCoder: 的类的子类也必须覆盖此方法并返回 YES。// 编写解码数据的方法时应参考安全编码指南。

目标-C:

@property (class, readonly) BOOL supportsSecureCoding;
Run Code Online (Sandbox Code Playgroud)

迅速:

public static var supportsSecureCoding: Bool { get }
Run Code Online (Sandbox Code Playgroud)

我正在使用 Xcode 10.0,在 Swift 4.0 和 Swift 4.2 上都尝试过。人们如何解决这个问题?任何帮助表示赞赏。

更新:使用 时public class var supportsSecureCoding,它会编译,但在使用Optimize for …

nssecurecoding swift

3
推荐指数
2
解决办法
1174
查看次数

使用decodeObject(of:forKey :)解码符合协议的对象

我有一个Objective-C协议,需要遵守NSSecureCoding

@protocol MyProtocol <NSObject, NSSecureCoding>
…
@end
Run Code Online (Sandbox Code Playgroud)

我有一个父对象,该对象存储对符合标准的对象的引用MyProtocol,我希望父对象也符合NSSecureCoding。当我尝试这个:

required init?(coder aDecoder: NSCoder) {

    if let childObject = aDecoder.decodeObject(of: MyProtocol.self, forKey: "childObject") {
        self. childObject = childObject
    } else {
        return nil
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到错误:'decodeObject(of:forKey:)' is unavailable in Swift: use generic 'decodeObjectOfClass(_:forKey:)'

如果您不知道所编码对象的特定类,是否可以使用NSSecureCoding?

protocols ios nssecurecoding swift

2
推荐指数
1
解决办法
395
查看次数

如何使用NSSecureCoding保证集合类的内容?

我有一个class对象,该对象SGBContainer具有一个名为class 的数组objects,其中包含class对象SGBObject。当前,它们各自实现NSCoding,但不实现NSSecureCoding。在-initWithCoder:SGBContainer这个样子的:

- (id)initWithCoder:(NSCoder *)aCoder
{
    self = [self init];
    if (self)
    {
        _objects = [aCoder decodeObjectForKey:@"objects"];
    }
}
Run Code Online (Sandbox Code Playgroud)

我想切换为使用NSSecureCoding,据我所知,这意味着将上述内容更改为:

- (id)initWithCoder:(NSCoder *)aCoder
{
    self = [self init];
    if (self)
    {
        _objects = [aCoder decodeObjectOfClass:[NSArray class] forKey:@"objects"];
    }
}
Run Code Online (Sandbox Code Playgroud)

...没有太大的改进,因为无论其类如何,数组的内容都会被实例化。如何确保数组仅包含类对象SGBObject而不实例化它们?

objective-c nscoding nssecurecoding

1
推荐指数
1
解决办法
1999
查看次数

NSSecureCoding 与 Keychain

我了解使用“NSSecureCoding”可以安全地将数据存储到磁盘,类似于钥匙串作为安全存储信息的地方。

我还了解钥匙串具有在同一提供商的应用程序之间共享的优势。如果人们忽略钥匙串共享功能,是否可以说,与 NSSecureCoding 相比,将数据存储在钥匙串中同样安全?

我有一个用户对象

class User: NSObject, NSSecureCoding {

private enum CodingKeys: String, CodingKey {
    case test
}

public static var supportsSecureCoding: Bool {

    return true
}

override init() {}

var test: String = "teeees"


func encode(with aCoder: NSCoder) {

    aCoder.encode(self.test as NSString)
}

required init?(coder aDecoder: NSCoder) {

    test = aDecoder.decodeObject(of: NSString.self, forKey: CodingKeys.test.rawValue)! as String
}
}
Run Code Online (Sandbox Code Playgroud)

我存档的

let user = User()
    let data = NSKeyedArchiver.archivedData(withRootObject: user)

    try! data.write(to: DocumentHelper.cashURLForID(id: "TTYYUU"))
Run Code Online (Sandbox Code Playgroud)

TTYYUU的内容是:

6270 6c69 7374 3030 d401 …

security keychain banking nssecurecoding swift

1
推荐指数
1
解决办法
866
查看次数