Post not yet marked as solved
I’m developing a macOS app that uses a proprietary Core ML model, which I need to encrypt. Since Core ML doesn’t support model encryption on macOS, I plan to encrypt the model myself using a symmetric key and decrypt it at runtime. To minimize the possibility of the model being compromised, I’d like to ensure that the decrypted model is only accessible in-memory, not on-disk. So my app will load the encrypted data, decrypt it with CryptoKit, construct an MLModelAsset with the decrypted data, and load that with MLModel.load(MLModelAsset...).
The part I’m stuck on is constructing the MLModelAsset. It only has one initializer method: init(specification: Data), where specification is described as “[t]he contents of a .mlmodel as a data blob.” My model is in the .mlpackage format, which is a macOS package (i.e. a directory, not a blob). Attempting to initialize MLModelAsset with the (unencrypted) .mlmodel file stored inside the .mlpackage (under “Data/com.apple.CoreML/model.mlmodel”) throws an error:
testLoadingPlainTextModel(): failed: caught error: "Error Domain=com.apple.CoreML Code=0 "compiler error: Encountered an error while compiling a neural network model: in operation op_7_to_fp16: Cannot interpret @model_path when ModelPath is unset" UserInfo={NSLocalizedDescription=compiler error: Encountered an error while compiling a neural network model: in operation op_7_to_fp16: Cannot interpret @model_path when ModelPath is unset}"
Since .mlpackage stores the model architecture and the weights in separate files, this isn’t unexpected. But I have no idea how to load the .mlpackage (or the corresponding .mlmodelc) as a blob, since they’re both directories and Data(contentsOf:) throws an error if you try to load them.
(Note: I’m testing all this without any encryption for the time being—neither the .mlpackage or .mlmodelc is encrypted in my test project.)
What am I doing wrong? Is there any way to load an .mlpackage or .mlmodelc package as a blob, for instantiating MLModelAsset? Or is there a different/better way to encrypt Core ML models on macOS?
Thanks!
Post not yet marked as solved
Hi!
With CryptoKit functions i can instantiate certificate keys, but with usage of Security module the code fails. I cannot figure out what is the issue.
Anyone have any idea what needs to be changed?
Thanks!!!, Garfield
This is the code that causes issue:
import Security
import CryptoKit
// base64 encoded
let privateKeyString = "deXnwQoRHddejAMvHsucXdPkE0B5hAIap1VE69ASplo="
let publicKeyString = "p4Rqbh+nmv/FslbJFGOe7JzSP6/ySaTkgW6h5t/+fqC/E8M9SVmamBKdTusddEecWY5KBGZo4x2oeNYyM7EtPA=="
let attributesPrivate: [NSObject : NSObject] = [
kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeyClass: kSecAttrKeyClassPrivate
]
let attributesPublic: [NSObject : NSObject] = [
kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeyClass: kSecAttrKeyClassPublic
]
var errorPrivate: Unmanaged<CFError>?
var errorPublic: Unmanaged<CFError>?
var error: Unmanaged<CFError>?
if #available(iOS 13.0, *) {
let publicKeyX = try! P256.Signing.PublicKey(rawRepresentation: Data(base64Encoded: publicKeyString)!.suffix(65))
//https://developer.apple.com/forums/thread/680554
print(publicKeyX, "P256 PUBLIC")
let privateKeyX = try! P256.Signing.PrivateKey(rawRepresentation: Data(base64Encoded: privateKeyString)!.suffix(65))
print(privateKeyX, "P256 PRIVATE")
} else {
// Fallback on earlier versions
}
let publicKey = SecKeyCreateWithData(Data(base64Encoded: publicKeyString)! as NSData, attributesPublic as NSDictionary, &errorPublic)!
let privateKey = SecKeyCreateWithData(Data(base64Encoded: privateKeyString)! as NSData, attributesPrivate as NSDictionary, &errorPrivate)!
Post not yet marked as solved
Hello, I came on this forum to ask if there were any other developers or teams currently working on the Swift Based Blockchain protocol for Apple to make "Dapples"?
I was hoping that someone would guide me in the right direction as far as exporting my solidity based smart contract application into swift / into Xcode. I cannot find out how to connect solidity and Xcode to make Dapps, and I was wondering if anyone was working on making the official smart contract for Swift IOS?
thank you,
Dylan Kawalec
DYLANKAWALEC@GMAIL.COM
9284990093
Post not yet marked as solved
I'm pretty new to RSA Keys and Certificates and all of that. So I'm
getting a PEM File from a network request, I understand the PEM file is
basically the certificate without header and footer, so essentially I
have a string. I need to create a PublicKey from that in order to
Encrypt some text, but I think I'm doing something wrong. This is my
code so far, I have talked to other teams (Android) and when they print
out the Encrypted Data, they are getting a regular String and I'm
getting lots of weird characters. Thanks in advance guys! (:
func encryptBase64(text: String, certificateStr: String) throws -> Data {
let encryptionError = EncrpytionError(message: "There has been an issue with encryption")
guard
let certData = Data(base64Encoded: certificateStr),
let certificate = SecCertificateCreateWithData(nil, certData as CFData),
let publicKey = SecCertificateCopyKey(certificate)
else {
throw encryptionError
}
let algorithm: SecKeyAlgorithm = .rsaEncryptionOAEPSHA256AESGCM
guard SecKeyIsAlgorithmSupported(publicKey, .encrypt, algorithm) else {
throw encryptionError
}
guard let cipherText = SecKeyCreateEncryptedData(
publicKey,
algorithm,
text.data(using: .utf8)! as CFData, nil)
else {
throw encryptionError
}
return cipherText as Data
}
And when I try to print cipherText as a String using
let encryptedString = String(decoding: encryptedData, as: UTF8.self)
I just get this weird thing:
"D�aj�\\m꒤h,�A�{��8�~�\nY\u0003F�Cˤ�@��\"�\u0018�\u0007\u001fX@VC�U_��E\u0005dž1���X��\/4Px��P\u0016�8}% ��<��@�I_�K\u000e�\bR*�� ���斋�7,�%���F^q�\u0000\\�'�ZTD\u0013Q�_\u0010\u001f>i]&��B���@1\u0006\b��E\u0004�F���yS\u0013�3����SB)��m\u0017%��5ʲ����s\u0003��r�&�?�8b��W@\u001e��؞ۡ��8�s~��ӹ�u\"�2��U�&\b�3XV���˔Y��xt[\fm&P:\\�\f� y��6jy"
Android team is doing something like this using Kotlin:
private fun extractPublicKey(certificateString: String): PublicKey {
val encodedCertificateBytes = certificateString.toByteArray()
val decodedCertificateBytes = Base64.decode(encodedCertificateBytes, Base64.DEFAULT)
val inStream = decodedCertificateBytes.inputStream()
val certificateFactory = CertificateFactory.getInstance("X.509")
val certificate = certificateFactory.generateCertificate(inStream)
inStream.close()
return certificate.publicKey
}
Post not yet marked as solved
My need is to efficiently detects if OS supports secure enclave. There seems to be one way to decide if the Secure Enclave is present: Create an elliptic curve encryption key in the Secure Enclave, If this fails, and the error has a code of -4 = errSecUnimplemented, then there is no Secure Enclave.
My question, is there any way other approach to detect if system supports secure enclave?
I have a continuous data stream encrypted by aesgcm, I did not find a way to decrypt it using CryptoKit unless I have the full data.
My question is Can CryptoKit decrypt or encrypt a stream without a complete read? Like EVP_***_Update in OpenSSL.
Thank you.
Post not yet marked as solved
Hi
I have code that uses SecKeyEncrypt to encrypt a string.
SecKeyEncrypt(publickeysi!, SecPadding.PKCS1, aString, aString.count, &messageEncrypted, &messageEncryptedSize)
This works across all devices, given identical source string, except the recently released iPhone 14 and Pro models. Simulator works across the board.
Is there any reason why these devices would result in a B64 encoded string along the lines of
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
where all other devices return an appropriate B64 string, such as
DNfdGmJW8DOeuwB9DZxMjY/qcJHgKCewMd/Hi3m1vkHxdRaeQbYvFbmnJwtcudnqm9cRiT/cee1ls5Hm6bcmVtGPf23O4SnOha97MhrJIaUWOumUdRfKd5PYVd74NVuWPfQ+VHlKFQtiVjBNvNntiZmadBEV95BwRcxFWSVLDG7tfgzM2tNvYsDG+ZwN0r3F1AX4IH/Ggor9Dk//26c5WZ50HzwfkeY122qMDIj2LDCUGXXhXzkvSyEYFReJhscwtXdDk1nN49jrDB5bEUD9Xn1xZzlghpcSNC4DKqP/3TSuwqcHZ7g/BfYcRVtXeWGqUxeeQcaTNulUggCWWGdtJw==
It appears that SecKeyEncrypt is deprecated in iOS 15 but I am struggling to find an appropriate alternative if that is even the issue.
Thanks
Post not yet marked as solved
Hi, I am trying to implement encryption and decryption with EC signing keys. in the process I am getting the following error while creating a SecKey from the private key.
Error in creating a secKey Optional(Swift.Unmanaged<__C.CFErrorRef>(_value: Error Domain=NSOSStatusErrorDomain Code=-50 "EC private key creation from data failed" (paramErr: error in user parameter list) UserInfo={numberOfErrorsDeep=0, NSDescription=EC private key creation from data failed}))
Code snippet for decryption
func decrypt(data: Data, key: SecureEnclave.P256.Signing.PrivateKey) throws -> Data? {
var error: Unmanaged<CFError>?
let privateKeyData: CFData = key.dataRepresentation as CFData
let privateKeyAttributes = [kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeyClass: kSecAttrKeyClassPrivate] as CFDictionary
guard let SecKey = SecKeyCreateWithData(privateKeyData, privateKeyAttributes as CFDictionary, &error)
else {
print("Error in creating a secKey", error)
return nil
}
guard SecKeyIsAlgorithmSupported(SecKey, .decrypt, EncryptAndDecryptAlogrithm)
else {
print("Decryption algorithm is not supported", error)
return nil
}
guard let decryptedData = SecKeyCreateDecryptedData(SecKey, EncryptAndDecryptAlogrithm, data as CFData, &error) else {
print("Error in decryption", error)
return nil
}
return decryptedData as Data
}
let data = Data(base64Encoded: "BNtHrb1cZuflSDZz+E3PnIkLtYUQuBDW+ONlzuAypZcQa+5oKv0L0wSIBMMseMr0roloexPwTaVV26ddewTP0+vRt9v6uLOg366cElMo6P5nh2K7xKi1PMcRyBVel+Kq9WQWT/EkRIuUkHdq2KLXy/Q=")!
let alice = try SecureEnclave.P256.Signing.PrivateKey()
let decryptedData = try decrypt(data: data, key:alice)
Thank you in advance.
Post not yet marked as solved
Parallel Android code is below:
public static String getEncryptedText(String plainText, SecretKey secretKey) {
if(plainText == null) {
plainText = "";
}
try {
byte[] ivBytes = new byte[GCM_IV_LENGTH];
SecureRandom random = new SecureRandom();
random.nextBytes(ivBytes);
String iv = Base64.getEncoder().encodeToString(ivBytes);
byte[] cipherText = encrypt(plainText.getBytes(), secretKey, ivBytes);
String text = Base64.getEncoder().encodeToString(cipherText);
text = iv+text;
return text;
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
private static byte[] encrypt(byte[] plaintext, SecretKey key, byte[] nonce) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);
Post not yet marked as solved
I have 2 apps, I use HMAC for signature between apps. First App's minimum deployment target is 11.2 and it uses CryptoSwift for sending data to the second app while signing documents. But the Second app uses Apple's CryptoKit, and I get a signing error. Can I use different packages for HMAC Sha256 process?
Post not yet marked as solved
Hi,
is there any chance for X448 and Ed448 elliptic curve support in CryptoKit (or other security framework) anytime soon? I need to support this curve in my project and really like to avoid messing with OpenSSL or other third party libs.
Thanks much
Matt
HI all,
I am trying to implement diffie-hellman key exchnage, by generating a secret key with an EC public key receives from API and the private key already generated in the project. Also I need to perform the KDF operation by passing some parameters. Here what my project code look like
generating the secret key
func generateSharedSecret(issuerPublicKey: SecKey, devicePrivateKey: SecKey, parameters:[SecKeyKeyExchangeParameter: Any] = [:]) throws -> Data? {
var error: Unmanaged<CFError>?
guard let shared = SecKeyCopyKeyExchangeResult(devicePrivateKey, .ecdhKeyExchangeStandard, issuerPublicKey, parameters as CFDictionary, &error) else {
let errStr = error?.takeRetainedValue().localizedDescription ?? "Derive Key Fail"
print(errStr)
throw error!.takeRetainedValue() as Error
}
return shared as Data
}
Setup parameters for performing secret key operation and KDF
var algId: Data, keyDataLen: Int
algId = "".data(using: .utf8)!
keyDataLen = 256
let algorithmID = prefixedBigEndenLen(from: algId)
let partyUInfo = prefixedBigEndenLen(from: apu)
let partyVInfo = prefixedBigEndenLen(from: apv)
let suppPubInfo = intToData(value: UInt32(keyDataLen).bigEndian)
let suppPrivInfo = Data()
let concatedData = algorithmID + partyUInfo + partyVInfo + suppPubInfo + suppPrivInfo
let params = [SecKeyKeyExchangeParameter.requestedSize: 32, SecKeyKeyExchangeParameter.sharedInfo: concatedData] as [SecKeyKeyExchangeParameter : Any]
// Function call:
let sharedSecret = try generateSharedSecret(issuerPublicKey: pubKey, devicePrivateKey: eprivKey, parameters: params as [SecKeyKeyExchangeParameter : Any])
By using the resulting generated secret key I have performed the JWE encryption and got some encrypted string as output. The problem what I am facing it is not decrypting on the server side and server returns "Unable to parse error".
Can anyone let me know, is it the correct way to generate a secret key? What am I doing wrong here?
Thanks
Post not yet marked as solved
We have the below Implementation in Android and the same has to be integrated into Swift.
Key :- "d95acd54b4a821ff32c52825q931c194"
IV :- "687b9509c25a34b8ad076346s8353d67"
Here Both the Key and IV are 32 bits and below is the android code.
public class AESEncryption {
private static final String key = "d95acd54c6a821ff32c52825b931c194";
private static final String initVector = "687b9509c25a14b8ad076346d8353d67";
static byte[] bte = hexToBytes(initVector);
public static String encrypt(String strToEncrypt) {
try {
CommonCode.showLog("log", bte.toString());
IvParameterSpec iv = new IvParameterSpec(bte);
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
CommonCode.showLog("IV after logs", iv.toString());
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(strToEncrypt.getBytes());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return Base64.getEncoder().encodeToString(encrypted).trim();
} else {
return android.util.Base64.encodeToString(encrypted, android.util.Base64.DEFAULT).trim();
}
} catch (Exception e) {
CommonCode.showLog("Error while encrypting: ", e.toString());
}
return null;
}
public static String decrypt(String strToDecrypt) {
try {
IvParameterSpec iv = new IvParameterSpec(bte);
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
} else {
return new String(cipher.doFinal(android.util.Base64.decode(strToDecrypt, android.util.Base64.DEFAULT)));
}
} catch (Exception e) {
CommonCode.showLog("Error while decrypting: " , e.toString());
}
return null;
}
}
How can we mimic the above in Swift?
Here in Android they are using static byte[] bte = hexToBytes(initVector); to convert the 32bit IV into 16 bit Bytes Array
I Have Tried the same approach on Swift below are the code snippet
[Contents.swift](https://developer.apple.com/forums/content/attachment/60fab4f2-1496-4003-9f37-c195de95e94a)
I am trying to create a jwt token signed with Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve and the SHA-256 hash algorithm.
The payload and the header are created properly, but I am having problems signing it.
The P256.Signing.PrivateKey(rawRepresentation: keyData) always returns nil.
Can anyone please help?
let privateKey = """
-----BEGIN ENCRYPTED PRIVATE KEY-----
code
-----END ENCRYPTED PRIVATE KEY-----
"""
let keyData = Data(base64Encoded: privateKey.toBase64())!
let header = jwtHeader()
let payload = jwtPayload()
let signingInput = "\(header).\(payload)"
let privateKey = try! P256.Signing.PrivateKey(rawRepresentation: keyData)
let sig = try! privateKey.signature(for: Data(signingInput.utf8)).rawRepresentation
return "\(signingInput).\(sig.base64URLEncodedString)"
extension String {
func toBase64() -> String {
return Data(self.utf8).base64EncodedString()
}
}
Post not yet marked as solved
Hello,
I am trying to verify a EC publicKey(prime256v1) fingerprint generated by Ruby by using Swift's CryptoKit but I did't find any source or an example to verify the publicKey fingerprint. Someone please help me to provide a way to do verify in Swift?
Example code to generate fingerprint in Ruby.
OpenSSL::PKey::EC.new(public_key)
fingerprint = key.fingerprint("sha256")
Example PublicKey and its fingerprint
PublicKey
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJAZCn9MKy4TRr7GPcEdkgrVK0EAE
fsASHQW4hOOj0UtIWAd7e1xT60zVeFPKKJrB7v5OE9Ha/Xs01IcSsVgE1w==
-----END PUBLIC KEY-----
Fingerprint
SHA256:5r1Tcd4ZGfnY+NQIhXHx6mSGB4rz59JK0lrVUZoXNPI
Post not yet marked as solved
Hi,
Not working and error above.
let key512 = SymmetricKey(size: .init(bitCount: 512))
let encryptedData512 = try ChaChaPoly.seal(clear_data2!, using: key512).combined
If I change the bitcount to 256, no error.
Same error even if I use AES.GCM
Thanks
Post not yet marked as solved
Can't seem to get CryptoKit to import. Is there some other configuration setting, etc. I need to fix? I though all you need to do in a playground is the import statement.
My code looks like this:
import UIKit
import CryptoKit
let string = "Hello world"
let data = Data(string.utf8)
let digest = SHA256.hash(data: data)
let hash = digest.compactMap { String(format: "%02x", $0)}.joined()
print("The hash is \(hash)")
Basically, I can't use any method from CryptoKit although when I was typing the import statement, soon as I typed 'Cr' I was prompted with the fill of 'CryptoKit'. It also working in an IoS project in Swift. So I know it's there. Just won't work in the playground. I get the following error message:
error: Couldn't lookup symbols:
static CryptoKit.HashFunction.hash<τ_0_0 where τ_1_0: Foundation.DataProtocol>(data: τ_1_0) -> τ_0_0.Digest
static CryptoKit.HashFunction.hash<τ_0_0 where τ_1_0: Foundation.DataProtocol>(data: τ_1_0) -> τ_0_0.Digest
static CryptoKit.HashFunction.hash<τ_0_0 where τ_1_0: Foundation.DataProtocol>(data: τ_1_0) -> τ_0_0.Digest
static CryptoKit.HashFunction.hash<τ_0_0 where τ_1_0: Foundation.DataProtocol>(data: τ_1_0) -> τ_0_0.Digest
static CryptoKit.HashFunction.hash<τ_0_0 where τ_1_0: Foundation.DataProtocol>(data: τ_1_0) -> τ_0_0.Digest
Appreciate any insights.
Thanks
Post not yet marked as solved
I am slightly confused as to how I am supposed to maintain persistent access to a SecureEnclave.P256.Signing.PrivateKey. Do I have to persist the key myself (using its dataRepresentation property and code along the lines of Storing CryptoKit Keys in the Keychain or is there another persistent reference to the key inside the Secure Enclave that I can use later?
Post not yet marked as solved
General:
Apple Platform Security support document
Security Overview
Cryptography:
DevForums tags: Security, Apple CryptoKit
Security framework documentation
Apple CryptoKit framework documentation
Common Crypto man pages — For the full list of pages, run:
% man -k 3cc
For more information about man pages, see Reading UNIX Manual Pages.
On Cryptographic Key Formats DevForums post
SecItem attributes for keys DevForums post
CryptoCompatibility sample code
Keychain:
DevForums tags: Security
Security > Keychain Items documentation
On Mac Keychains DevForums post
Smart cards and other secure tokens:
DevForums tag: CryptoTokenKit
CryptoTokenKit framework documentation
Mac-specific frameworks:
DevForums tags: Security Foundation, Security Interface
Security Foundation framework documentation
Security Interface framework documentation
Related:
Networking Resources — This covers high-level network security, including HTTPS and TLS.
Network Extension Resources — This covers low-level network security, including VPN and content filters.
Code Signing Resources
Notarisation Resources
Trusted Execution Resources — This includes Gatekeeper.
App Sandbox Resources
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Post not yet marked as solved
Hi,
I want to use the iOs Secure Enclave to create a "Primary Device" Mechanism. It would work like this.
Device Creates Enclave Key Pair and Sends the Public Key to the Server (Preferably Node JS)
The Server encrypts a random message with the Public Key and sends it to the Device. I can be sure the Device is the only one able to decipher that string, because the private key is safe in the Secure Enclave
Now the client would decrypt the message and send the result to the server which can compare it to the original message.
When de- and encrypting Data in the ios ecosystem the process is straightforward. I Encrypt Data using SecKeyCreateEncryptedData and Decrypt using SecKeyCreateDecryptedData passing Public Key and CipherText Objects.
Now my question is: how can I export the public Key to have my Node JS Backend encrypt Messages which will be decryptable again with the SecureEnclave.