Apple CryptoKit

RSS for tag

Perform cryptographic operations securely and efficiently using Apple CryptoKit.

Apple CryptoKit Documentation

Pinned Posts

Posts under Apple CryptoKit tag

32 Posts
Sort by:
Post not yet marked as solved
8 Replies
7.0k Views
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)
Posted
by
Post not yet marked as solved
5 Replies
3.2k Views
Hello, I'm working with Cryptokit and I'm currently unable to export a P256 ECDSA signature data to base64Encoding and convert it back to derRepresentation. Here is my code: let privateKey = P256.Signing.PrivateKey() //Generated successfully /* For example pemRepresentation: -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgK+lUhkqFo637XuvJ Q6YiqZx04c33UUyWnLnpwfTwrtChRANCAARy55pVFhjgq3jKnQTx7s1XDIaNm20m 29ZEiBJnvzYfQGUQ+4ldzJYm34z8W2X/waqTqXsY4/oSO1sDFSQ6XwrG -----END PRIVATE KEY----- */ let publicKey = privateKey.publicKey //Picked up successfully /* For example pemRepresentation: -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcueaVRYY4Kt4yp0E8e7NVwyGjZtt JtvWRIgSZ782H0BlEPuJXcyWJt+M/Ftl/8Gqk6l7GOP6EjtbAxUkOl8Kxg== -----END PUBLIC KEY----- */ //Basic message to test, "something" here let messageDigest = "something".data(using: .utf8)!                  let signature = try privateKey.signature(for: messageDigest) //Successfully generated                  //Now from the PublicKey, let's check the signature for the message let isValidSignature = publicKey.isValidSignature(signature, for: messageDigest) //Successfully Return true //So far everything works fine //Now lets try to export the derRepresentation of the signature we just created to a base64EncodedString and try to use it later let signDataDerRepresentation = signature.derRepresentation //Here the signDataDerRepresentation is 70 bytes length //Here we get the signature derRepresentation to base64EncodedString, perfect to export let signDataDerRepresentationBase64String = signature.derRepresentation.base64EncodedString() /* "MEQCIGVC/zOGKEauy9AetVViTZiMTtFIeNtW9xALMTu6aIjSAiB+QPz9nGwzy51k3p3osu9OY6oQXkuLHTPoSWxPorg8GA==" */ //Here the signDataDerRepresentationBase64String is 96 bytes length //Now when I try to create a signature from a derRepresentation it works fine when I use the original derRepresentation data: let signature1 = try! P256.Signing.ECDSASignature(derRepresentation: signDataDerRepresentation) //signature1 is created //But when I try to create exactly the same signature from the base64EncodedString, an exception is throw //Convert base64String to Data let signDataDerRepresentationBase64StringData = signDataDerRepresentationBase64String.data(using: .utf8)! do { //Try to create a signature from the base64EncodedData of de the derRepresentation let signature2 = try P256.Signing.ECDSASignature(derRepresentation: signDataDerRepresentationBase64StringData) //Here it fails, signature2 is not created }catch{ //It fails with error: invalidASN1Object print("Signature failed \(error)") /* Signature failed invalidASN1Object */ } So now, I would like to know how to convert de derRepresentation of the signature I created into a base64EncodedString to the derRepresentation the ECDSASignature(derRepresentation:) func is looking for to create a signature from derRepresentation? I don't understand how I can convert my base64 String into that derRepresentation this func is looking for, I can't find the doc : /// An ECDSA (Elliptic Curve Digital Signature Algorithm) Signature @available(iOS 13.0, macOS 10.15, watchOS 6.0, tvOS 13.0, *) extension P256.Signing {     public struct ECDSASignature : ContiguousBytes {         /// Returns the raw signature.         /// The raw signature format for ECDSA is r || s         public var rawRepresentation: Data         /// Initializes ECDSASignature from the raw representation.         /// The raw signature format for ECDSA is r || s         /// As defined in https://tools.ietf.org/html/rfc4754         public init<D>(rawRepresentation: D) throws where D : DataProtocol         /// Initializes ECDSASignature from the DER representation.         public init<D>(derRepresentation: D) throws where D : DataProtocol         /// Calls the given closure with the contents of underlying storage.         ///         /// - note: Calling `withUnsafeBytes` multiple times does not guarantee that         ///         the same buffer pointer will be passed in every time.         /// - warning: The buffer argument to the body should not be stored or used         ///            outside of the lifetime of the call to the closure.         public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R         /// A DER-encoded representation of the signature         public var derRepresentation: Data { get }     } } Thank you for your help. Hélie
Posted
by
Post not yet marked as solved
0 Replies
2k Views
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 TN3137 On Mac keychain APIs and implementations SecItem Fundamentals DevForums post SecItem Pitfalls and Best Practices DevForums post Investigating hard-to-reproduce keychain problems 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"
Posted
by
Post not yet marked as solved
7 Replies
1.9k Views
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?
Posted
by
Post not yet marked as solved
7 Replies
2.9k Views
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&lt;__C.CFErrorRef&gt;(_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 -&gt; Data? {     var error: Unmanaged&lt;CFError&gt;?     let privateKeyData: CFData = key.dataRepresentation as CFData     let privateKeyAttributes = [kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,                                 kSecAttrKeyClass: kSecAttrKeyClassPrivate] as CFDictionary     guard let SecKey = SecKeyCreateWithData(privateKeyData, privateKeyAttributes as CFDictionary, &amp;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, &amp;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.
Posted
by
Post not yet marked as solved
6 Replies
1.5k Views
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?
Posted
by
Post marked as solved
11 Replies
2k Views
My end goal is to use eciesEncryptionCofactorX963SHA256AESGCM with a key generated on the Secure Enclave using CryptoKit, that requires Biometric Authentication. CryptoKit does not implement the ECIES encryption algorithms, so my goal was to fall back to the Security framework. The public key can be easily converted to a SecKey because it implements x963Representation which can then be imported as follows: let enclaveSecKey: SecKey = SecKeyCreateWithData(enclaveKey.x963Representation as CFData, [ kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeyClass: kSecAttrKeyClassPublic, kSecAttrKeySizeInBits: 256 ] as [String: Any] as CFDictionary, nil), I have everything working except the code to decrypt with the private key. Naturally, the Secure Enclave does not expose the private key - as is its design - rather some kind of token? I did read the Keychain documentation which notes that it is not possible to simply obtain an x963Representation of the private key (as it's a custom representation returned by the Secure Enclave). However, my ultimate question is this: can one convert the Secure Enclave representation into something that can be used as a SecKey for encryption/decryption (without necessarily being stored in the Keychain - i.e., 'correct') as it seems both CryptoKit and Security have a means of representing the private key token returned by the Secure Enclave? (Or is one's only recourse to use the Security framework for generating and storing the keys too?) I have also tried this code to create a SecKey representation, having retrieved the GenericPasswordConvertible out of the keychain (note the use of kSecAttrTokenID: kSecAttrTokenIDSecureEnclave) with the aforementioned goal of loading the Secure Enclave's private token as a SecKey: let enclaveSecKey: SecKey = SecKeyCreateWithData(enclaveKey.rawRepresentation as CFData, [ kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeyClass: kSecAttrKeyClassPrivate, kSecAttrTokenID: kSecAttrTokenIDSecureEnclave, kSecAttrAccessible: kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, kSecUseAuthenticationContext: try await createAuthContext( reason: "Decrypt data", fallbackTitle: "Enter your device password to decrypt data", mustEvaluate: true ), kSecAttrIsPermanent: true, kSecAttrIsExtractable: false, kSecAttrSynchronizable: false, kSecAttrKeySizeInBits: 256, kSecAttrAccessControl: SecAccessControlCreateWithFlags( nil, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, [.biometryAny, .privateKeyUsage], &cfSecKeyCreateError )! ] as [String: Any] as CFDictionary, nil) This works, in and of itself, (i.e., it loads without error and cfSecKeyCreateError is nil, however when I try SecSecKeyCopyPublicKey I get a different, incorrect public key and - naturally, I suppose - if I attempt to decrypt data with the private key that fails with: Optional(Swift.Unmanaged<__C.CFErrorRef>(_value: Error Domain=NSOSStatusErrorDomain Code=-50 "ECIES: Failed to aes-gcm decrypt data (err -69)" UserInfo={numberOfErrorsDeep=0, NSDescription=ECIES: Failed to aes-gcm decrypt data (err -69)}))
Posted
by
Post not yet marked as solved
1 Replies
759 Views
Hi All. I have a need to store encrypted data on device. The data is arriving from multiple services in our app in the form of one line of text at a time. This data has to be decrypted on a server, probably using Java. In Java, there is concept of a CipherStream. I'll init that stream with a private key and IV (nonce), and feed it data as I get it. Once done, I can close the stream, and I have an encrypted file. In IOS, I'm trying to emulate that process. However, the concept of SealedBox seems to be getting in the way. I can seal each piece of text, but decrypting those doesn't work. I believe this has to do with the way the data is produced by the box. I can decrypt each piece individually, but I can't find a way to feed this into a stream and ultimately seal the whole thing. I understand I can write the file plain text, and encrypt it at the end, but this leaves the data vulnerable for long periods of time. Anyone has any Ideas on how to solve this on IOS?
Posted
by
Post not yet marked as solved
0 Replies
813 Views
I am trying to build csr string from publickeyBits and signature from dongle. Below is the swift code portion for generating csr. public func buildCSRAndReturnStringUsingDongle(enrollmentId: String, password: String) -> String? { let tagPublic = "public" + enrollmentId self.dongle = DongleManager.getInstance() self.dongle?.generateKeyPair(enrollmentId: enrollmentId, password: password) let publicKeyFromDongle: String = (self.dongle?.getPublicKeyBits(enrollmentId: enrollmentId, password: password))! print("Public Key is: \n",publicKeyFromDongle) let keyDict: [NSString: Any] = [ kSecAttrKeyType: kSecAttrKeyTypeRSA, kSecAttrKeyClass: kSecAttrKeyClassPublic, kSecAttrKeySizeInBits: 2048 as Any, kSecAttrApplicationTag: tagPublic.data(using: .utf8), ] var error: Unmanaged<CFError>? let publicKeyFromDongleData = Data.init(base64Encoded: publicKeyFromDongle) guard let publicKeySecKey = SecKeyCreateWithData(publicKeyFromDongleData! as CFData, keyDict as CFDictionary, &error) else { print("Failed to create public key:", error!.takeRetainedValue()) return nil } let publickeyBits = KeyPairManager.getInstance().getPublicKeyBits(publicKey: publicKeySecKey, enrollmentId: enrollmentId).0 let certificationRequestInfo = buldCertificationRequestInfo(publickeyBits!) let bytes: [UInt8] = certificationRequestInfo.map { $0 } let certificationRequestStr = String(decoding: bytes, as: UTF8.self) let signaturedString = self.dongle?.sign(password: password, data : certificationRequestStr, enrollmentId: enrollmentId) var signature = [UInt8](repeating: 0, count: 256) var signatureLen: Int = signature.count let signatureData = signaturedString!.data(using: .hexadecimal) signatureData!.copyBytes(to: &signature, count: signatureData!.count) signatureLen = signatureData!.count print("signature length: " + String(signatureLen)) print("signature: "+signatureData!.base64EncodedString()) var certificationRequest = Data(capacity: 1024) certificationRequest.append(certificationRequestInfo) let shaBytes = keyAlgorithm.sequenceObjectEncryptionType certificationRequest.append(shaBytes, count: shaBytes.count) var signData = Data(capacity: 2049) let zero: UInt8 = 0 // Prepend zero signData.append(zero) signData.append(signature, count: signatureLen) appendBITSTRING(signData, into: &certificationRequest) enclose(&certificationRequest, by: sequenceTag) // Enclose into SEQUENCE let csrString = certificationRequest.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0)) .addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) print(csrString) let head = "-----BEGIN CERTIFICATE REQUEST-----\n" let foot = "-----END CERTIFICATE REQUEST-----\n" var isMultiple = false var newCSRString = head //Check if string size is a multiple of 64 if csrString!.count % 64 == 0 { isMultiple = true } for (integer, character) in csrString!.enumerated() { newCSRString.append(character) if (integer != 0) && ((integer + 1) % 64 == 0) { newCSRString.append("\n") } if (integer == csrString!.count-1) && !isMultiple { newCSRString.append("\n") } } newCSRString += foot return newCSRString } I wrote a Wrapper where sign function is as of given below. We had a getPublicBits() function here and i think that is working properly. So, I skip this here. - (NSString*) sign: (NSString*)password data: (NSString*)data enrollmentId: (NSString*)enrollmentId { Dongle *d = (Dongle*)****; char * pass = strdup([password UTF8String]); char * signDataStr = strdup([data UTF8String]); char * enId = strdup([enrollmentId UTF8String]); NSData* data2 = [data dataUsingEncoding:NSUTF8StringEncoding]; char *signData = (char *)[data2 bytes]; NSString* signaturedString = [NSString stringWithCString:d->sign(pass, signData, enId).c_str() encoding:[NSString defaultCStringEncoding]]; return signaturedString; } I used signUtil method from safenet sdk's library. std::string Dongle::signUtil(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPrivateKey, char* password, char* data) { //std::cout<<"data is: " << *data; CK_RV retCode = CKR_OK; int isPaddingRequired = 0; int isDataFromUser = 0; CK_MECHANISM mech; CK_BYTE pSigData[3000]; #ifndef PKCS11_V1 CK_ULONG usSigLen = sizeof(pSigData); #else CK_ULONG usSigLen = 0; #endif char *pInputData = 0; unsigned long ulInputDataLen = strlen(data); std::cout << "length: " << ulInputDataLen; CK_BYTE_PTR pInData = (CK_BYTE_PTR)data; std::cout << "Mechanism: [6]SHA256-RSA" <<std::endl; retCode = C_Login(hSession, CKU_USER, (CK_UTF8CHAR_PTR)password, strlen(password)); mech.mechanism = CKM_SHA256_RSA_PKCS; mech.pParameter = 0; mech.ulParameterLen = 0; isDataFromUser = 0; if( retCode == CKR_OK ) { if( isPaddingRequired ) { for(unsigned long ulLoop=ulInputDataLen; ulLoop<64; ++ulLoop) { pInData[ulLoop] = 0; } ulInputDataLen = 64; } } if (retCode == CKR_OK) { retCode = C_SignInit(hSession, &mech, hPrivateKey); } CK_ULONG usInLen = (CK_ULONG)ulInputDataLen; // get the signature length if(retCode == CKR_OK) { retCode = C_Sign(hSession, pInData, usInLen, (CK_BYTE_PTR)NULL_PTR, &usSigLen); } // get the signature if(retCode == CKR_OK) { retCode = C_Sign(hSession, pInData, usInLen, (CK_BYTE_PTR)pSigData, &usSigLen); } std::string returnSignature = ""; if( (retCode == CKR_OK) && usSigLen ) { std::cout << "Signed Data " << std::endl << "(hex) "; for(unsigned long ulLoop=0; ulLoop<usSigLen; ++ulLoop) { char pBuffer[25]; sprintf(pBuffer, "%02x", pSigData[ulLoop]); std::cout << pBuffer; returnSignature += pBuffer; } std::cout << std::endl; } // Release memory if( pInputData ) { delete pInputData; } return returnSignature; } I debug a lot and according to csr decoder, only the signature is invalid. public key and signature algorithm are valid.
Posted
by
Post not yet marked as solved
4 Replies
924 Views
I'm trying to implement client certificate authentication in the URLSessionDelegate.urlSession(:didReceive:completionHandler:) by using the URLCredential(identity:certificates:persistence:) and CryptoKit, but it appears this is currently not supported. On my client I generate a key and a CSR and after I sent that to the server, I receive an X.509 certificate which I store in the Keychain. I used to create the keys as SecKey objects, which were also stored in the Keychain; this works fine. Now I would like to use the CryptoKit keys, preferably the SecureEnclave.P256 ones. It appears that storing these keys, as suggested by Apple (generic passwords), does not create the SecIdentity I'm after that's needed to create the URLCredential, nor have I been able to transform a SecKey created in the Secure Enclave to a CryptoKit.SecureEnclave.P256 key. The SecKeyCopyExternalRepresentation function simply returns an error telling me that I cannot export Secure Enclave keys (which is weird, as CryptoKit's implementation does somewhat allow this). Also, the URLCredential.init does not allow you to add a private key directly, nor does the SecIdentity provide any way of manually creating it, by supplying the right keys and the right certificates. How can I use CryptoKit for client certificate authentication or how can I use CryptoKit or the older SecKey implementations to create SecIdentity or URLCredential objects that will work?
Posted
by
Post not yet marked as solved
0 Replies
709 Views
Hi guys, I need to use deterministic ECDSA (described in RFC 6979 article: https://www.rfc-editor.org/rfc/rfc6979) algorithm to calculate signature in iOS project. It is known that deterministic ECDSA is vulnerable to fault injection and side-channel attacks, so there is an updates for RFC 6979 described in following article (see section 4): https://www.ietf.org/archive/id/draft-mattsson-cfrg-det-sigs-with-noise-04.html#name-updates-to-rfc-6979-determi I tried to find any information related to deterministic ECDSA algorithm implementation and support in iOS ecosystem, but unfortunately found nothing Could you please provide me complete information whether the deterministic ECDSA with updates is implemented and provides by iOS API? Any guidance or information on this matter would be greatly appreciated. Looking forward for you soon. ))
Posted
by
Post not yet marked as solved
4 Replies
4.6k Views
I have a Build Phase which runs a script. The script is a swift file, which I have simplified to illustrate the crash, like so: #!/usr/bin/env xcrun --sdk macosx swift import Foundation import CryptoKit var sha256 = SHA256() // Do other stuff... All the Xcode 15 betas fail to build my app, instead throwing the error: Command PhaseScriptExecution failed with a nonzero exit code. The logs: JIT session error: Symbols not found: [ _$s9CryptoKit6SHA256VMa, _$s9CryptoKit6SHA256VACycfC ] Failed to materialize symbols: { (main, { _$s20PropertyListModifier6sha2569CryptoKit6SHA256Vvp, _main, __swift_FORCE_LOAD_$_swiftDarwin_$_PropertyListModifier, __swift_FORCE_LOAD_$_swiftIOKit_$_PropertyListModifier, ___swift_project_value_buffer, __swift_FORCE_LOAD_$_swiftFoundation_$_PropertyListModifier, ___swift_allocate_value_buffer, __swift_FORCE_LOAD_$_swiftObjectiveC_$_PropertyListModifier, __swift_FORCE_LOAD_$_swiftXPC_$_PropertyListModifier, __swift_FORCE_LOAD_$_swiftCoreFoundation_$_PropertyListModifier, __swift_FORCE_LOAD_$_swiftDispatch_$_PropertyListModifier }) } Does anyone know of a work-around or solution, or does this just look like nothing more than a bug in the betas, which I should "wait out"? It's had the same problem right from beta 1 to the current beta 5 so it's starting to look like it won't be fixed which is worrying me.
Posted
by
Post not yet marked as solved
2 Replies
674 Views
I've went through all the posts with similar info about signature or keys used not working with openssll. But I haven't been able to patch it all together. I will use some sample keys for what I tried, let privPem = """ -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgIUSrwhllMSminPZZ Gx0YHUsL12IWIGI+4yhejpq90HihRANCAAT6pxKtIKm4VbfXeKpQ7rxITlC6b18Q 0X+Iz1UVDolyjx79bt5vUp0mPJ6hHBnK/Ap5gXpv89wmLPp7/O2NconE -----END PRIVATE KEY----- """ let privKey = try! P256.Signing.PrivateKey(pemRepresentation: privPem) let pubKey = privKey.publicKey let challengeDev = "1122334455667788" let dataToSignDev = challengeDev.hexadecimal let digest = SHA256.hash(data: dataToSignDev!) let signatureForDigest = try! privKey.signature( for: digest) let signature1 = try! P256.Signing.ECDSASignature(derRepresentation: signatureForDigest.derRepresentation) let isValidSignature = pubKey.isValidSignature(signatureForDigest, for: digest) I have tried the same using Security framework also to no avail. What I tried is a direct application of what the openssl part does, So I have a device that will verify the signature that the iOS app will be sending. The public key is taken from a certificate I would share with the device. All data sent to the device including signature is in DER format. openssl dgst -sha256 -sign app_private.key -out %OUT_RESOURCES_DIR%\signature.der -binary device_challenge.hex openssl x509 -inform der -in cert.der -out cert.pem openssl x509 -pubkey -noout -in cert.pem &gt; public_key.pem openssl dgst -sha256 -verify public_key.pem -signature signature.der challenge.hex Here on the iOS side If I were to sign and verify everything is fine. But if the same signature is verified on OpenSSL it fails. I tried to create a DER file on the terminal but asn1parse fails on it, Test % echo 30450220198944e2a8352941036f227225940392cbd1bc720358ce29db29a2a85f2b2a30022100b4e75ceb0335e4b1955aab01edc8e7347f78dc627f8d02a78103cd9165571d57 &gt; signature1.der Test % openssl asn1parse -inform DER -in signature1.der 0:d=0 hl=2 l= 48 cons: PRINTABLESTRING Error in encoding 140704639042368:error:0DFFF09B:asn1 encoding routines:CRYPTO_internal:too long:/AppleInternal/Library/BuildRoots/97f6331a-ba75-11ed-a4bc-863efbbaf80d/Library/Caches/com.apple.xbs/Sources/libressl/libressl-3.3/crypto/asn1/asn1_lib.c:143: I'm assuming I need to manually do some changes to make them inter compatible? Like this post Can't export EC kSecAttrTokenIDSecureEnclave public key Not sure how to get there though. All help appreciated.
Posted
by
Post not yet marked as solved
1 Replies
671 Views
AES 128 CBC algorithm is not producing same results compared to Android code. We have all static strings for key, iv and salt, even then the IV we couldnt match and produce same output as android. This is the Android code, object AESEncyption { ​ fun encrypt(strToEncrypt: String) : String? { try { val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1") val spec: KeySpec = PBEKeySpec(secretKey.toCharArray(), hex(salt), iterationCount, keySize) val key: SecretKey = SecretKeySpec(factory.generateSecret(spec).encoded, "AES") cipher.init(Cipher.ENCRYPT_MODE, key, IvParameterSpec(hex(iv))) ​ return base64(cipher.doFinal(strToEncrypt.toByteArray(Charsets.UTF_8))) } catch (e: Exception) { Log.i("Him","Error while encrypting: $e") } return null } ​ private fun base64(bytes: ByteArray?): String { return android.util.Base64.encodeToString(bytes, android.util.Base64.DEFAULT) } ​ /* fun base64(str: String?): ByteArray? { return Base64.decodeBase64(str) }*/ ​ fun hex(bytes: ByteArray?): String? { return Hex.encodeHexString(bytes) } ​ fun hex(str: String): ByteArray? { return try { Hex.decodeHex(str.toCharArray()) } catch (e: DecoderException) { throw IllegalStateException(e) } } } iOS code is let enc = try AES(key: keyVar2!.bytes, blockMode: CBC(iv: iv.base64FromHex.ivToUInt8Array), padding: .pkcs5).encrypt(value.bytes) let encryptedData = Data(enc)
Posted
by
Post not yet marked as solved
2 Replies
862 Views
Hello, I am attempting to perform a Diffie Hellman Keyexchange with a server running on .Net. However, the secretKey I am creating on the client side does not match with the secretKey on the server side, which I have for testing purposes. I can import the server secret key as a SymetricKey, and if I use it to seal and open a box, it works. However, if I seal the box with my client key, I can not open it with the server shared key. I create the SymetricKey like this: let sharedHash = SHA256.self let sharedInfo = serverPublicKey.rawRepresentation let sharedLength = 32 let symetricKey = sharedSecret.x963DerivedSymmetricKey( using: sharedHash, sharedInfo: Data(), outputByteCount: sharedLength) The server key is created using .Net like this: bob.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash; bob.HashAlgorithm = CngAlgorithm.Sha256; bobPublicKey = bob.PublicKey.ToByteArray(); bobKey = bob.DeriveKeyMaterial(CngKey.Import(Alice.alicePublicKey, CngKeyBlobFormat.EccPublicBlob)); My assumption is the keys should be the same. Is that correct? How can I find out what format the server key is in? The .Net documentation is not particularly precise on that You can find a Playground of my code, and when you google for ECDiffieHellmanCng Class, you will find an example on what .Net does. Any help is appreciated
Posted
by
Post not yet marked as solved
0 Replies
541 Views
I try to use LAContext.evaluateAccessControl for LAAccessControlOperationUseKeyDecrypt operations using a Secure Enclave-based private key. The keys are created using SecKeyGeneratePair (ECDH + SETokenID). Access Control is then defined using kSecAccessControlBiometryAny | kSecAccessControlAnd | kSecAccessControlPrivateKeyUsage flags. By the time LAContext.evaluateAccessControl is called, SecAccessControlCreateWithFlags is used with flags kSecAccessControlBiometryAny | kSecAccessControlPrivateKeyUsage. Evaluation will fail with ACL error: Domain=com.apple.LocalAuthentication Code=-1009 "ACL operation is not allowed: 'od'" UserInfo={NSDebugDescription=ACL operation is not allowed: 'od’} The same process is fine for signature operations. I don't understand what 'od' stands for. If ACLs are the same for key creations and key usage, shouldn't it prompt TouchID and allow the operation ?
Posted
by
Post not yet marked as solved
1 Replies
490 Views
Hello Here is a problem with creating SecKey for ios 10 after key derivation (HMAC + sha512) After derivation we get 32 bytes of private key and chainCode There is no problem to use this bytes to create P256 private key with function from iOS13 try? P256.Signing.PrivateKey(rawRepresentation: bytes) and then to get x963Representation to create a SecKey But on iOS10 - 12 we don't have an ability to use this function... So I have to convert 32 bites key to 97 somehow to represent it in ANSI x9.63 format Example of key bytes [110, 181, 159, 0, 54, 16, 25, 129, 87, 128, 85, 36, 192, 64, 195, 4, 20, 47, 243, 134, 160, 57, 30, 210, 89, 225, 223, 114, 11, 121, 57, 156] x963Representation [4, 37, 167, 241, 121, 238, 41, 22, 35, 158, 89, 144, 215, 243, 4, 91, 217, 243, 23, 42, 171, 228, 247, 89, 136, 123, 22, 71, 11, 205, 134, 29, 110, 83, 241, 239, 135, 37, 226, 40, 179, 11, 191, 193, 232, 124, 41, 160, 136, 53, 95, 33, 233, 207, 151, 83, 136, 234, 97, 4, 79, 115, 227, 69, 42, 252, 66, 68, 64, 32, 176, 11, 75, 206, 158, 228, 246, 9, 179, 36, 94, 186, 209, 125, 152, 192, 192, 141, 242, 200, 108, 181, 75, 103, 86, 171, 231] I see that x963Representation contains: header(04) + ? + ? + 32_Key_Bytes So the question is - how to count x and y to get the key form (04 || X || Y || K) to be able to create SecKey?
Posted
by
Post not yet marked as solved
2 Replies
874 Views
Hi, I'm having some trouble running a shell script that worked before I updated the Xcode and my MacOS. This is probably connected to the command line tools which were updated with these upgrades. I can't switch to an older version of the command line tools to verify this theory tho... The script uses CryptoKit to decrypt some data which was encrypted using a SymmetricKey. The script: #!/bin/bash # # DecryptScript.sh # # This script decrypts encrypted data using a symmetric key. # Check for the correct number of arguments if [ "$#" -ne 2 ]; then echo "Usage: $0 <encrypted_file_path> <decrypted_file_path>" exit 1 fi # Get the input arguments encryptedFilePath="$1" decryptedFilePath="$2" # Find the path to the script's directory scriptDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # Check if the symmetric key file exists in the same directory symmetricKeyPath="$scriptDir/.sim.key" if [ ! -f "$symmetricKeyPath" ]; then echo "SymmetricKey file was not found in the same directory as the script." exit 1 fi # Decrypt the data swift - <<EOF import Foundation import CryptoKit let symmetricKeyURL = URL(fileURLWithPath: "$symmetricKeyPath") let encryptedDataURL = URL(fileURLWithPath: "$encryptedFilePath") let decryptedDataURL = URL(fileURLWithPath: "$decryptedFilePath") guard let symmetricKeyData = try? Data(contentsOf: symmetricKeyURL) else { fatalError("Failed to read symmetric key data") } guard let encryptedData = try? Data(contentsOf: encryptedDataURL) else { fatalError("Failed to read encrypted data") } do { // Decrypt the data using AES-GCM let decryptionKey = SymmetricKey(data: symmetricKeyData) let sealedBox = try AES.GCM.SealedBox(combined: encryptedData) let decryptedData = try AES.GCM.open(sealedBox, using: decryptionKey) // Write the decrypted data to a file try decryptedData.write(to: decryptedDataURL) print("Decryption successful. Decrypted file saved at \(decryptedDataURL)") } catch { print("Decryption failed: \(error.localizedDescription)") } EOF The code in the project which encrypts the data and retrieves the key: func encryptSymmetric(data: Data, password: String) throws -> (Data, Data) { let key = SymmetricKey(size: .bits256) guard let cipher = try? AES.GCM.seal(data, using: key).combined else { throw SomeCustomError.failedToEncryptData } let keyData = key.withUnsafeBytes { Data($0) } return (cipher, keyData) } The error I'm presented with in the terminal is JIT session error: Symbols not found: [ _$s9CryptoKit3AESO3GCMO4open_5using10Foundation4DataVAE9SealedBoxV_AA12SymmetricKeyVtKFZ, _$s9CryptoKit12SymmetricKeyVMa, _$s9CryptoKit3AESO3GCMO9SealedBoxV8combinedAGx_tKc10Foundation12DataProtocolRzlufC, _$s9CryptoKit12SymmetricKeyV4dataACx_tc10Foundation15ContiguousBytesRzlufC, _$s9CryptoKit3AESO3GCMO9SealedBoxVMa ] Failed to materialize symbols: { (main, { _$s4main16encryptedDataURL10Foundation0D0Vvp, _$s4main15symmetricKeyURL10Foundation0D0Vvp, _$s10Foundation4DataVAcA0B8ProtocolAAWL, _$s4main16decryptedDataURL10Foundation0D0Vvp, _$sSa12_endMutationyyF, _$ss5print_9separator10terminatoryypd_S2StFfA0_, _$ss27_finalizeUninitializedArrayySayxGABnlF, _main, _$s10Foundation4DataV15_RepresentationOWOe, _$sSSWOh, _$ss5print_9separator10terminatoryypd_S2StFfA1_, _$s10Foundation4DataV5write2to7optionsyAA3URLV_So20NSDataWritingOptionsVtKFfA0_, ___swift_allocate_value_buffer, __swift_FORCE_LOAD_$_swiftFoundation_$_main, _$s10Foundation4DataV10contentsOf7optionsAcA3URLVh_So20NSDataReadingOptionsVtKcfcfA0_, __swift_FORCE_LOAD_$_swiftXPC_$_main, _$s10Foundation4DataV15_RepresentationOWOy, ___swift_project_value_buffer, _$s10Foundation4DataVAcA0B8ProtocolAAWl, __swift_FORCE_LOAD_$_swiftIOKit_$_main, _$ss26DefaultStringInterpolationVWOh, __swift_FORCE_LOAD_$_swiftCoreFoundation_$_main, _$s10Foundation3URLVACs23CustomStringConvertibleAAWl, __swift_FORCE_LOAD_$_swiftDarwin_$_main, __swift_FORCE_LOAD_$_swiftObjectiveC_$_main, _$s10Foundation3URLVACs23CustomStringConvertibleAAWL, __swift_FORCE_LOAD_$_swiftDispatch_$_main }) } This leads me to believe that linking might not be working properly. I also found this thread where someone had the same issue but with a different framework. NOTE: If I try to decrypt the data in my project, it works without any issues even on Xcode 15. It only fails if I try to run this script which worked before when I had the previous version of command line tools. I even tried updating to Xcode 15.1 beta and its command line tools, without success. Any feedback is appreciated. Thank you.
Posted
by