我刚刚开始使用 CryptoKit 来替换旧的库。我的计划是在运行 iOS 13 及更高版本的手机上替换它,并在低于 13 的 iOS 版本上仍然使用旧库。但是我无法让应用程序在 iOS 12.4 中启动而不崩溃。我已经删除了其他所有内容,只添加了这些简单的线条
if #available(iOS 13.0, *) {
let nonce = try? AES.GCM.Nonce(data: iv)
}
Run Code Online (Sandbox Code Playgroud)
在#available我认为是用于确保如果条件不符合也就是被跳过。
奇怪的是应用程序崩溃了,我从来没有调用包含这些线的网格,只是将它们放在应用程序的某个地方会导致它崩溃。
我还在顶部(有和没有if canImport(CryptoKit))导入了 CryptoKit并且我已经添加@available(iOS 13.0, *)到类中。
谁能告诉我“排除”代码的正确方法,或者对于较低的 iOS 版本,正确的方法是什么。我想一定可以使用 iOS 13 特定的功能,同时仍然通过“旧”方法保持向后兼容性?
另外,我使用的是 Xcode 11,但我想这可能很明显。
我得到的错误是:
dyld: Library not loaded: /System/Library/Frameworks/CryptoKit.framework/CryptoKit
Run Code Online (Sandbox Code Playgroud)
编辑:现在我也试过把它放在整个班级(包括导入)
#if canImport(CryptoKit)
#endif
Run Code Online (Sandbox Code Playgroud)
而且,我注意到这条线可以存在而不会使应用程序崩溃:
let key = SymmetricKey(data: Data())
Run Code Online (Sandbox Code Playgroud)
对称密钥也是 CryptoKit 的一部分
编辑 2:我发现弱链接可以解决问题。我尝试使用其他新(iOS 13)框架之一 CryptoTokenKit,但遇到了同样的问题。但是在这里我可以添加框架并将链接设置为可选,从而解决了问题。但是,当向应用程序添加框架时,CryptoKit 由于某种原因不可用。
iOS 13的CryptoKit框架.rawRepresentation为ECDSA公钥和私钥提供了价值。我一直在尝试对rawRepresentation数据类型进行逆向工程,以便在它与JWK之间进行转换。从公钥表示形式的64字节长度来看,这似乎是一个简单的x || y串联。我猜想那会是私钥x || y || d,但是事实并非如此,因为这样做应该会产生96字节的字符串,而实际rawRepresentation是144字节。似乎也不是有效的DER / ASN.1字符串。我还没有找到符合我所得到的实际值的规格。
如您所料,Apple的文档具有很强的描述性。
rawRepresentation:私钥的表示形式,以字节的集合表示。
提供了十六进制的示例密钥对。
Private: 988f8187ff7f00007466815b0d6b02ae1a063198fd1e4923fb1e413195126cc00d30483284186b435726c0c69cc774274ea32eb6a17cbaf2ea88dd7f3a5a2a3ce637bc4b96523c2795035bd2fbeb093b010000000000000000000000000000000000000000000000000000000000000012b2b61abe8beae5aeb6d0bda739235364de96c7f498813cfb0336198dcf9063
Public: 2774c79cc6c02657436b18843248300dc06c129531411efb23491efd9831061a3b09ebfbd25b0395273c52964bbc37e63c2a5a3a7fdd88eaf2ba7ca1b62ea34e
Run Code Online (Sandbox Code Playgroud)
这是什么格式?
我正在寻找 CryptoKit 的设置/参数,这将允许我在 iOS 应用程序和 Java 应用程序之间共享数据。流程如下所示: - 使用 CryptoKit 使用固定密钥和随机初始化向量 (IV) 加密文本。- 在 Java 应用程序中,使用标准 javax 库使用相同的固定密钥执行解密。随机 IV 将与加密文本一起与应用程序传输/共享。
同样,反过来也是必需的,其中使用 JavaX 库使用固定密钥和随机 IV 对文本进行加密。随机 IV 和加密文本与 iOS 应用程序共享,它应该使用 CryptoKit 对其进行解密。
下面是Java中加密和解密的代码
public static byte[] encrypt(byte[] plaintext, byte[] key, byte[] IV) throws Exception
{
// Get Cipher Instance
Cipher cipher = Cipher.getInstance("AES_256/GCM/NoPadding");
// Create SecretKeySpec
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
// Create GCMParameterSpec
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);
// Initialize Cipher for ENCRYPT_MODE
cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec); …Run Code Online (Sandbox Code Playgroud) 我正在使用 Apple 的新 cryptokit 库,并试图获得一个基本的用例来工作。
目标:我想通过 cryptokit 在安全飞地中创建私钥,将密钥的引用存储在 iOS 设备的钥匙链中,并确保只有在用户通过某种生物识别技术对自己进行身份验证后才能在安全飞地中重新初始化密钥身份验证方法。
当前状态:到目前为止,我可以通过以下代码在安全飞地中初始化私钥:
var privateKeyReference = try CryptoKit.SecureEnclave.P256.KeyAgreement.PrivateKey.init();
Run Code Online (Sandbox Code Playgroud)
此外,我可以从钥匙链中存储和检索相应私钥的引用。检索引用后,我可以使用以下代码重新初始化安全飞地中的私钥:
var privateKeyReference = getPrivateKeyReferenceFromKeyChain();
var privateKey = try CryptoKit.SecureEnclave.P256.KeyAgreement.PrivateKey.init(
dataRepresentation: privateKeyReference
);
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都按预期进行,并且所有使用私钥的加密操作都成功。
现在,据我了解Apple 的备用文档,我应该能够将私钥的第一次初始化修改为如下所示。
let authContext = LAContext();
let accessCtrl = SecAccessControlCreateWithFlags(
kCFAllocatorDefault,
kSecAttrAccesibleWhenUnlockedThisDeviceOnly,
[.privateKeyUsage, .userPresence, .biometryCurrentSet],
nil
);
var privateKeyReference = try CryptoKit.SecureEnclave.P256.KeyAgreement.PrivateKey.init(
accessControl: accessCtrl!,
authenticationContext: authContext
);
Run Code Online (Sandbox Code Playgroud)
从而,确保只有当用户通过某种生物特征认证方法对自己进行身份验证时,私钥才能被重新初始化。初始初始化仍然有效,没有任何错误。
问题:但是,添加前面的代码后,我没有收到任何生物识别身份验证提示,并且在重新初始化后根本无法使用私钥。每当我尝试使用重新初始化的密钥执行某些加密操作时,都会记录以下错误,例如此处的一些签名:
Error Domain=CryptoTokenKit Code=-9 "setoken: unable to sign digest" UserInfo={NSLocalizedDescription=setoken: unable to sign digest})
Run Code Online (Sandbox Code Playgroud)
据我从这里猜测,我认为这 …
我在 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 输出中查看它。总的来说,我只是不是很熟悉UnsafeRawBufferPointer或ContiguousBytes。
我在 iOS 应用程序(我的第一个应用程序)上遇到了一些障碍,我想加密发送到服务器的数据。
为此,我生成一个存储在钥匙串中的对称密钥。
密钥通过以下方式生成:
SymmetricKey(data: password)
Run Code Online (Sandbox Code Playgroud)
在此函数中,密码实际上是计算得出的 SHA256,如下所示:
SHA256.hash(data: password)它为我提供了一个摘要,并从中提取数据表示以创建我的密钥。
现在,当我加密数据时,我会执行以下操作
var encryptedData: Data = Data()
if let key: SymmetricKey = try? readKey(account: encryptingKeyAccount){
encryptedData = try! ChaChaPoly.seal(rawData, using: key).combined
}
return encryptedData
Run Code Online (Sandbox Code Playgroud)
这会返回我然后发送到服务器的数据。
为了解密数据,我执行以下操作:
var decryptedData: Data = Data()
if let key: SymmetricKey = try? readKey(account: encryptingKeyAccount) {
let sealedBox = try! ChaChaPoly.SealedBox(combined: encryptedData)
decryptedData = try! ChaChaPoly.open(sealedBox, using: key)
}
return decryptedData
Run Code Online (Sandbox Code Playgroud)
现在我的问题是,如果我注销(这意味着从手机中删除密钥)并重新登录(在我看来,这会重新创建之前创建的相同密钥),那么我将无法解密我的数据......我有当我尝试打开盒子时出现以下错误:
Thread 1: Fatal error: 'try!' expression unexpectedly raised an error: CryptoKit.CryptoKitError.authenticationFailure
Run Code Online (Sandbox Code Playgroud)
我相信这是由于我创建密钥的方式所致,该密钥与之前删除的密钥不同......
我怎样才能解决这个问题 …
鉴于以下情况HashedAuthenticationCode:
import CryptoKit
let key = SymmetricKey(size: .bits256)
let message = "Hello world!".data(using: .utf8)!
let authenticationCode = HMAC<SHA256>.authenticationCode(for: message, using: key)
print(authenticationCode) // "HMAC with SHA256: c818a1400a9995d5faafbb5d41cc88a6701b5d1a4ded8ac169498319a2597e2a"
Run Code Online (Sandbox Code Playgroud)
我如何访问该c818a1400a9995d5faafbb5d41cc88a6701b5d1a4ded8ac169498319a2597e2a值?最终,这必须通过 a 进行编码和序列化URLSession,但我看不到获取 HAC 的“代码”部分的明显属性!
我想使用 Apples CryptoKit 将加密数据从运行 kotlin 应用程序的服务器发送到 iOS 应用程序。我在初始化AES.GCM.SealedBox和解密数据时遇到问题。总的来说,我不明白 Sealboxstag的用途。
所以首先是 Kotlin 方面:
fun ByteArray.aesEncrypt(key: ByteArray, iv: ByteArray? = null): ByteArray {
return aes(this, Cipher.ENCRYPT_MODE, key, iv)
}
private fun aes(self: ByteArray, mode: Int, key: ByteArray, iv: ByteArray?): ByteArray{
val skey = SecretKeySpec(key, "AES")
val cipher = Cipher.getInstance("AES/GCM/PKCS5Padding")
println("MODE: ${cipher.algorithm}")
iv?.let {
cipher.init(mode, skey, GCMParameterSpec(128, iv))
}?: run{
cipher.init(mode, skey)
}
val cipherText = ByteArray(cipher.getOutputSize(self.size))
var ctLength = cipher.update(self, 0, self.size, cipherText, 0)
ctLength += cipher.doFinal(cipherText, ctLength) …Run Code Online (Sandbox Code Playgroud) 我正在尝试将一个小的 swift 程序“ main.swift ”编译为Ubuntu 18.08 上的可执行文件。我使用Swift 包管理器来管理我的依赖项。在这个非常简单的情况下,我只有一个依赖项,即这个开源 CryptoKit。我有一个 swift 文件,它只是尝试导入 CryptoKit。
import Foundation
import CryptoKit
print("phew")
Run Code Online (Sandbox Code Playgroud)
我的Package.swift文件如下所示:
// swift-tools-version:5.2
import PackageDescription
let package = Package(
name: "decryp",
dependencies: [
.package(url: "https://github.com/apple/swift-crypto.git", .upToNextMajor(from: "1.0.1"))
],
targets: [
.target(
name: "decryp",
dependencies: ["swift-crypto"]
),
.testTarget(
name: "decrypTests",
dependencies: ["decryp"]),
]
)
Run Code Online (Sandbox Code Playgroud)
当我尝试使用swift build构建可执行文件时,它会获取存储库,但随后会出现未找到产品的错误。来自快速构建的标准输出:
Fetching https://github.com/apple/swift-crypto.git
Cloning https://github.com/apple/swift-crypto.git
Resolving https://github.com/apple/swift-crypto.git at 1.0.2
'decryp' /home/kah/decryp: error: product 'swift-crypto' not found. It is required by target …Run Code Online (Sandbox Code Playgroud) 我是 CryptoKit 的新手,我正在努力将此代码从 Node.js 转换为 Swift(使用 CryptoKit)。
// create a sha256 hmac with the secret
var hmac = crypto.createHmac('sha256', key);
return hmac.update(what).digest('base64');
Run Code Online (Sandbox Code Playgroud)
我在 Swift/CryptoKit 上做的是:
var hmac = SHA256.hash(data: Data(base64Encoded: key)!)
Run Code Online (Sandbox Code Playgroud)
但我不知道如何处理第二行。在 Ruby 上可以这样完成:
HMAC.digest('sha256', secret, what)
Run Code Online (Sandbox Code Playgroud)
但是 CryptoKit“没有”这个方法,有什么想法吗?
假设我使用 openssl 创建一个 x25519 密钥对,它将输出一个 64 字节私钥和相应的 44 字节 Base64 编码公钥,如下所示
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VuBCIEIMBF8S7zUco4bRrMiIuyTcSYU/rAVlNtE8SMYWphUatw
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VuAyEAE0eiiP0PKjy9AVM/0z2ZIZn453WSJNemrQ58HAXDaX0=
-----END PUBLIC KEY-----
Run Code Online (Sandbox Code Playgroud)
Swift CryptoKit 仅接受私钥和公钥初始化各 32 个字节。
如果我理解正确的话,64 字节私钥是种子,其中前 32 字节是实际私钥。
尽管如此,对公钥使用相同的原理是行不通的(这并不令人惊讶)
现在的问题是:如何将公钥转换为 Swift CryptoKit 所需的 32 字节?
这是使用 Base64 解码公钥的前 32 个字节的无效示例
let base64PublicKey = Data(base64Encoded: "MCowBQYDK2VuAyEAE0eiiP0PKjy9AVM/0z2ZIZn453WSJNemrQ58HAXDaX0=")!.dropLast(12)
let publicKey = try! Curve25519.KeyAgreement.PublicKey(rawRepresentation: rawPublicKey)
Run Code Online (Sandbox Code Playgroud) 我正在尝试在 UserDefaults 中存储和检索我的加密文本数据,但检索它时出现问题。我使用 CryptoKit 来加密和解密数据。
错误消息是:“无法将‘Foundation.__NSSwiftData’(0x7fff89d1ee50)类型的值转换为‘CryptoKit.ChaChaPoly.SealedBox’(0x7fff8085abc8)。”
有没有更好的方法将 SymmetricKey 存储在钥匙串中,而无需通过 UnsafeBytes 将其转换为 String?我使用 SwiftKeychainWrapper。
func encrypt(text: String) {
let key = SymmetricKey(size: .bits256)
let message = text.data(using: .utf8)!
let sealedBox = try! ChaChaPoly.seal(message, using: key)
let defaults = UserDefaults.standard
defaults.set(sealedBox.combined, forKey: "sealedBox")
let savedKey = key.withUnsafeBytes {Data(Array($0)).base64EncodedString()}
Services.saveKey(key: savedKey)
}
func decrypt() {
let savedKey = Services.getKey()
if let keyData = Data(base64Encoded: savedKey) {
let retrievedKey = SymmetricKey(data: keyData)
let defaults = UserDefaults.standard
let sealedBox = (defaults.object(forKey: "sealedBox") as? ChaChaPoly.SealedBox)!
let …Run Code Online (Sandbox Code Playgroud) 有谁知道一种无需将整个文件加载到内存中即可计算文件的 de SHA-256 哈希的方法?
我会非常适合使用苹果的 CryptoKit 库
apple-cryptokit ×13
swift ×13
encryption ×3
ios ×3
cryptography ×2
aes ×1
binary-data ×1
ecdsa ×1
ios13 ×1
java ×1
javax.crypto ×1
key-pair ×1
kotlin ×1
openssl ×1
x25519 ×1
xcode ×1