首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于iOS的NSValueTransformer核心数据加密

基于iOS的NSValueTransformer核心数据加密
EN

Stack Overflow用户
提问于 2015-10-16 13:55:20
回答 2查看 1.2K关注 0票数 3

我正在试验用核心数据和CommonCrypto加密数据。我正在尝试使用NSValueTransformer来懒惰地加密和解密。

但是,当我现在尝试将加密的数据保存到持久存储协调器时,它失败了。每次我试图将数据保存到数据库时,它都会给我:

-__NSCFString字节:发送到实例的不可识别的选择器

我确信这是某种数据库和NSManagedObject的错配,但我无法弄清楚。我觉得这可能很简单,但我找不到解决办法。我的代码:

NSValueTransformer

代码语言:javascript
复制
class TryHardEncryption: NSValueTransformer {

override class func transformedValueClass() -> AnyClass {
    return NSString.self
}

override class func allowsReverseTransformation() -> Bool {
    return true
}


override func reverseTransformedValue(value: AnyObject?) -> AnyObject? {
    if let message = value as? NSString {
        let keyString        = "12345678901234567890123456789012"
        let keyData: NSData! = (keyString as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
        let keyBytes         = UnsafeMutablePointer<Void>(keyData.bytes)
        print("keyLength   = \(keyData.length), keyData   = \(keyData)")

        let data: NSData! = (message as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
        let dataLength    = size_t(data.length)
        let dataBytes     = UnsafeMutablePointer<Void>(data.bytes)
        print("dataLength  = \(dataLength), data      = \(data)")

        let cryptData    = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)
        let cryptPointer = UnsafeMutablePointer<Void>(cryptData!.mutableBytes)
        let cryptLength  = size_t(cryptData!.length)

        let keyLength              = size_t(kCCKeySizeAES256)
        let operation: CCOperation = UInt32(kCCDecrypt)
        let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
        let options:   CCOptions   = UInt32(kCCOptionPKCS7Padding + kCCOptionECBMode)

        var numBytesEncrypted :size_t = 0

        let cryptStatus = CCCrypt(operation,
            algoritm,
            options,
            keyBytes, keyLength,
            nil,
            dataBytes, dataLength,
            cryptPointer, cryptLength,
            &numBytesEncrypted)

        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
            //  let x: UInt = numBytesEncrypted
            cryptData!.length = Int(numBytesEncrypted)
            print("DecryptcryptLength = \(numBytesEncrypted), Decrypt = \(cryptData)")

            // Not all data is a UTF-8 string so Base64 is used
            let base64cryptString = cryptData!.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
            print("base64DecryptString = \(base64cryptString)")
            print( "utf8 actual string = \(NSString(data: cryptData!, encoding: NSUTF8StringEncoding))");
            return base64cryptString
        } else {
            print("Error: \(cryptStatus)")
        }
    }
    return nil
}

override func transformedValue(value: AnyObject?) -> AnyObject? {
    if let message = value as? NSString {
        let keyString        = "12345678901234567890123456789012"
        let keyData: NSData! = (keyString as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
        let keyBytes         = UnsafePointer<UInt8>(keyData.bytes)
        print("keyLength   = \(keyData.length), keyData   = \(keyData)")

        let data: NSData! = message.dataUsingEncoding(NSUTF8StringEncoding) as NSData!
        let dataLength    = Int(data.length)
        let dataBytes     = UnsafePointer<UInt8>(data.bytes)
        print("dataLength  = \(dataLength), data      = \(data)")

        let cryptData    = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)!
        let cryptPointer = UnsafeMutablePointer<UInt8>(cryptData.mutableBytes)
        let cryptLength  = size_t(cryptData.length)

        let keyLength              = size_t(kCCKeySizeAES256)
        let operation: CCOperation = UInt32(kCCEncrypt)
        let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
        let options:   CCOptions   = UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding)

        var numBytesEncrypted :size_t = 0

        let cryptStatus = CCCrypt(operation,
            algoritm,
            options,
            keyBytes, keyLength,
            nil,
            dataBytes, dataLength,
            cryptPointer, cryptLength,
            &numBytesEncrypted)

        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
            cryptData.length = Int(numBytesEncrypted)
            print("cryptLength = \(numBytesEncrypted), cryptData = \(cryptData)")

            // Not all data is a UTF-8 string so Base64 is used
            let base64cryptString = cryptData.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
            print("base64cryptString = \(base64cryptString)")
            return NSString(string: base64cryptString) as NSObject

        } else {
            print("Error: \(cryptStatus)")
        }
    }
    return nil
}

}

为了让NSValueTransformer工作,我必须做的是:

代码语言:javascript
复制
let transformer: TryHardEncryption = TryHardEncryption()
    NSValueTransformer.setValueTransformer(transformer, forName: "TryHardEncryption")

如果没有上面的代码,就不会调用NSValueTransformer。

我将数据库字段标记为可转换类型,并将其命名为: TryHardEncryption。你们知道这是怎么回事吗?

编辑它所涉及的属性是:

代码语言:javascript
复制
@NSManaged var establishmentDescription: String?

当我调试加密和解密函数时,它们都返回一个字符串。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-23 06:54:37

我终于想出来了..。我搞不懂什么类型非常对象必须是什么,我的confused转换器必须返回什么。我没有将值转换成nil转换器中的适当类型,因此我在代码中返回了0。然而,它并没有崩溃的方式,我可以很容易地弄清楚这一点。其次,我将实体列更改为NSObject。在transformedValue方法中返回一个transformedValue对象,在reverseTransformedValue方法中返回一个NSString。实际上,这就是我要做的一切。非常感谢你的帮助。这确实是一个类型错误。

票数 0
EN

Stack Overflow用户

发布于 2016-04-14 20:43:01

若要帮助任何想要查看更正代码示例的人,请将问题中transformedValue()的返回行替换为:return base64cryptString.dataUsingEncoding(NSUTF8StringEncoding)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33172285

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档