如何访问 CryptoKit 中 SymmetricKey 的底层密钥?

Eug*_*ene 5 swift apple-cryptokit

我在 Xcode 11.0 beta 2 上使用 Apple 的新CryptoKit框架。我想创建一个SymmetricKey,然后获取密钥的原始字节。我想使用这些字节来创建相同的密钥,然后检查以确保密钥相等。根据我在文档中的理解,访问密钥原始字节的唯一方法是使用withUnsafeBytes(_:)方法。我有一个带有以下代码的游乐场:

import Foundation
import CryptoKit

let key1 = SymmetricKey(size: .bits256)
key1.withUnsafeBytes { body in
  let rawKeyBytes = body.load(as: Data.self)
  let key2 = SymmetricKey(data: rawKeyBytes)
  print("Are they equal? \(key1 == key2)")
}
Run Code Online (Sandbox Code Playgroud)

这个的输出是Are they equal? false,所以不幸的是键不匹配。假设我可以让这些键匹配,我也不确定如何转换rawKeyBytes为字符串以便在我的 Playground 输出中查看它。总的来说,我只是不是很熟悉UnsafeRawBufferPointerContiguousBytes

Jul*_*ñoz 7

像您说的那样将一把钥匙与另一把钥匙进行比较是没有意义的。如果要提取密钥,请使用以下简单的行:

let keyb64 = key.withUnsafeBytes {
    return Data(Array($0)).base64EncodedString()
}
Run Code Online (Sandbox Code Playgroud)

或者删除base64EncodedString()仅用于Data发送到服务器或放入钥匙串中。

此致


Rob*_*ier 6

我不相信你可以使用loadData相当的方式。但无论如何,你想要的看起来像这样:

let key1 = SymmetricKey(size: .bits256)
let key2 = key1.withUnsafeBytes { SymmetricKey(data: Data($0)) }
print("Are they equal? \(key1 == key2)")
Run Code Online (Sandbox Code Playgroud)

在它自己的withUnsafeBytes块中访问一个值通常是危险的(例如,访问key1inside key1.withUnsafeBytes)。我不记得在这种特定情况下它是否被禁止,但作为一项规则,您应该避免它,因为它会导致独占访问冲突。


小智 5

我不得不做同样的事情,最后做了一些扩展来简化流程:

import CryptoKit
import Foundation

extension SymmetricKey {

    // MARK: Custom Initializers

    /// Creates a `SymmetricKey` from a Base64-encoded `String`.
    ///
    /// - Parameter base64EncodedString: The Base64-encoded string from which to generate the `SymmetricKey`.
    init?(base64EncodedString: String) {
        guard let data = Data(base64Encoded: base64EncodedString) else {
            return nil
        }

        self.init(data: data)
    }

    // MARK: - Instance Methods

    /// Serializes a `SymmetricKey` to a Base64-encoded `String`.
    func serialize() -> String {
        return self.withUnsafeBytes { body in
            Data(body).base64EncodedString()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并像这样测试:

import CryptoKit

func symmetricKeyTest() {
    let symmetricKey = SymmetricKey(size: .bits256)
    let serializedSymmetricKey = symmetricKey.serialize()

    guard let deserializedSymmetricKey = SymmetricKey(base64EncodedString: serializedSymmetricKey) else {
        print("deserializedSymmetricKey was nil.")
        return
    }

    print("Keys match: \(symmetricKey == deserializedSymmetricKey)")
}
Run Code Online (Sandbox Code Playgroud)


小智 -1

以下似乎对我有用

import CryptoKit
import Foundation

let key1 = SymmetricKey(size: .bits256)
key1.withUnsafeBytes { ptr in
    let rawKeyBytes = Data(bytes: ptr.baseAddress!, count: ptr.count)
    let key2 = SymmetricKey(data: rawKeyBytes)
    print("Are they equal? \(key1 == key2)")
}
Run Code Online (Sandbox Code Playgroud)