Apple CryptoKit

RSS for tag

Perform cryptographic operations securely and efficiently using Apple CryptoKit.

Posts under Apple CryptoKit tag

96 Posts

Post

Replies

Boosts

Views

Activity

p256 signature using cryptokit fails verification on openssl
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 > 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 > 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.
3
0
1.4k
Aug ’23
Diffie Hellman Key exchange with .Net Cryptography
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
2
0
1.4k
Aug ’23
AES-128 CBC Pk5 result differs with Android code
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)
2
0
1.1k
Aug ’23
Xcode 15 beta Command PhaseScriptExecution failed with a nonzero exit code
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.
4
0
7.6k
Aug ’23
Deterministic ECDSA algorithm iOS side Implementation.
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. ))
0
0
1k
Jul ’23
Client certificate using CryptoKit
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?
4
0
1.8k
Jul ’23
Signature is shown as invalid while creating csr using publicKey and sign csr with private key from Dongle
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*)dong; 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.
0
0
1.2k
Jun ’23
CryptoKit and Security Framework (ECIES) interoperability
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)}))
11
0
3.8k
Jun ’23
How to persist SecureEnclave.P256.Signing.PrivateKey
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?
7
0
3.1k
Jun ’23
[IOS] Swift Cryptokit - P256 ECDSA Signature derRepresentation incompatibility
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
5
0
4.3k
Jun ’23
CryptoKit - AES.GCM - How do I encrypt a stream written to disk ( Looking for CipherStream basically)
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?
1
0
1.3k
Apr ’23
How to detect if OS supports secure enclave?
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?
6
0
2.3k
Apr ’23
Best practices for generating a 'Sign In with Apple' nonce on the client
When implementing SiwA on the client, you have the option of passing a nonce to a ASAuthorizationOpenIDRequest (docs). Here's a snippet of the relevant code that could be part of a SiwA implementation: let appleIDProvider = ASAuthorizationAppleIDProvider() let request = appleIDProvider.createRequest() request.requestedScopes = [.fullName, .email] request.nonce = /* What should this look like? */ let authorizationController = ASAuthorizationController(authorizationRequests: [request]) My core question is: are there any restrictions on its length and allowed characters? A similar conversation has been had on this SO post, but I'd like to know if there are any nonce generation implications from a SiwA perspective, as opposed to another auth service provider. The SecRandomCopyBytes docs include the following snippet: var bytes = [Int8](repeating: 0, count: 10) let status = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes) if status == errSecSuccess { // Always test the status. print(bytes) // Prints something different every time you run. } Could the result here be used as a SiwA nonce? Should I instead use the random bytes to index into an alphanumeric array of characters so my nonce contains alphanumerics rather than just numbers? CryptoKit also includes the following API that looks relevant: let nonce = ChaChaPoly.Nonce() The docs say this is a 12-byte nonce– can I throw that in a string and use it? I'd appreciate any clarification on generating nonces for the ASAuthorizationOpenIDRequest API? Thanks!
0
2
1.1k
Apr ’23
How to generate PEM from Curve25519 public key
I want to use ECC (curve25519) with Diffie-Hellman Key exchange. Backend is using ECC with X9.62 and PKCS#8 encoding. I want to achieve same on iOS so that I can fetch data from backed, decrypt it and show it to user. I tried this code but didn't work func getPEM() -> String { let keyPair = Curve25519.Signing.PrivateKey() let pubKey = keyPair.publicKey let pem = "-----BEGIN PUBLIC KEY-----\(pubKey.rawRepresentation.base64EncodedString())-----END PUBLIC KEY-----" return pem } After searching on Google I found that In order to get PEM we need DER and ASN1 from my public key but they are not supported by CryptoKit. Android is able to get right PEM using bouncycastle. Just for reference I am posting snippet from android code base. import org.bouncycastle.asn1.x9.X9ECParameters import org.bouncycastle.crypto.ec.CustomNamedCurves import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util import org.bouncycastle.jce.provider.BouncyCastleProvider import java.security.* import java.security.spec.ECParameterSpec import java.security.spec.InvalidKeySpecException import java.security.spec.PKCS8EncodedKeySpec import java.security.spec.X509EncodedKeySpec object CryptoKeyGenerator { init { Security.removeProvider(BOUNCY_CASTLE_IDENTIFIER) Security.addProvider(BouncyCastleProvider()) } fun getClientKeyMaterial(): String { val keyPair = generateEphemeralKeyPair() val pemEncodedPublicKey = getPEMEncodedStream(keyPair.public, false) return pemEncodedPublicKey } private fun getPEMEncodedStream(key: Key, privateKey: Boolean): String { val pkcS8EncodedKeySpec = PKCS8EncodedKeySpec(key.encoded) val stringBuilder = StringBuilder() val keyType = if(privateKey) PRIVATE_KEY else PUBLIC_KEY stringBuilder.append(KEY_HEADER_START + keyType + KEY_HEADER_END) stringBuilder.append(CryptoUtils.getBase64Encoded(pkcS8EncodedKeySpec.encoded)) stringBuilder.append(KEY_FOOTER_START + keyType + KEY_HEADER_END) return stringBuilder.toString() } /** * This method generates an ECC KeyPair with Curve25519 specs */ private fun generateEphemeralKeyPair(): KeyPair { val keyPairGenerator = KeyPairGenerator.getInstance(EC_ALGO_IDENTIFIER, BOUNCY_CASTLE_IDENTIFIER) val eccParameters: X9ECParameters = CustomNamedCurves.getByName(ECC_CURVE_SPEC) val eccSpec: ECParameterSpec = EC5Util.convertToSpec(eccParameters) keyPairGenerator.initialize(eccSpec) return keyPairGenerator.generateKeyPair() } } Android generated PEM of public key look like this -----BEGIN PUBLIC KEY-----MIIBMTCB6gYHKoZIzj0CATCB3gIBATArBgcqhkjOPQEBAiB/////////////////////////////////////////7TBEBCAqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqYSRShRAQge0Je0Je0Je0Je0Je0Je0Je0Je0Je0Je0JgtenHcQyGQEQQQqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq0kWiCuGaG4oIa04B7dLHdI0UySPU1+bXxhsinpxaJ+ztPZAiAQAAAAAAAAAAAAAAAAAAAAFN753qL3nNZYEmMaXPXT7QIBCANCAAQwsdIRTVn2+6rlgqAhVvx7ERj/Oku0wHmZZU1OST617h95ygSP5zJOa9lNiKqZMArjtJh7yQ4rg7kUq08Nv8+Q-----END PUBLIC KEY----- Other references: This repo has code for C, Java and nodejs https://github.com/Sahamati/rahasya
2
0
1.1k
Apr ’23
Cryptokit - How to get PEM representation of Curve25519 Public Key
Hi, How do I generate the pem representation of a curve25519 public key? I can generate the key using :      let privateKey = Curve25519.KeyAgreement.PrivateKey() let publicKey = privateKey.publicKey print(publicKey.rawRepresentation.base64EncodedString()) This prints a string like this : GyQfzi3bLfpDpzi8e9j6lovX15EZY1t1fQQcnJlURxI= But the expected strings are more like : ----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEApxUNh3jHlNSAWE7fadipsh9AjXv6439VY3EWEC5kbgY=\n-----END PUBLIC KEY Even if I add the " -----BEGIN PUBLIC KEY-----" and "-----END PUBLIC KEY-----" tags, it still doesn't process the key. So what format is exactly the base64 encoded string of the raw format of curve25519 public key? And how do I generate the public key pem format? The requirement is for Swift iOS.
7
0
3.4k
Apr ’23
Can CryptoKit ECDH Public Keys be identity keys?
Hi, I'm using CryptoKit to implement a spec that uses ECDH using P256. The spec says that one should check that the computed shared secret is not all 0x00 bytes. I understand that this can only happen if one of both keys used is the identity point on the curve. Does CryptoKit guarantee that P256.KeyAgreement.PublicKeys can never be the identity point by construction? (as e.g. the Rust elliptic_curve public keys do, according to their documentation)
4
0
1.5k
Feb ’23
How to create Private SecKey from modulus and private exponent
I am working on an application on IOS and I need to be able to decrypt an element that has been encrypted with a public key, but I only know the modulus and the private exponent of the private key. How can I obtain the private key from these elements in IOS? In java, with the following code I can get the private key from these elements and I can decrypt the element. final RSAPrivateKeySpec privateSpec = new RSAPrivateKeySpec(MODULUS, PRIVATE_EXPONENT); final KeyFactory factory = KeyFactory.getInstance("RSA"); final PrivateKey priv = factory.generatePrivate(privateSpec); On ios, I got the following code, but it doesn't return the private key:      let smodulus = "00c35d6ac32d287dab681c78272931b60ca442bd4505e1b306432af92ef6e07bc3e4e24c2bc2dac69c94753390c3793b80734ef906520a96cafb146ce587ab383e78efc58c5ccf56b5084f3f9bc719e646a0361155ab56b7d71b49f1f90673383ea0fdb4a67900c0973930aa3bc7071c479b4a5d229fcab7ce22b84c1637d7e70b"     let sPrivateExponent = "1f2535700832fc55e73322b49b8ca14942a6a125efda1b805414f5c4d6f6d2c45828fb9bbe64c2651405db42a8e71ae54f7cb7969a5db5cc865aab41ac6f4f77deccb51496fe588f9dcd724a1d49cab96712621afc9c656c56dea011f8ab8e12a321fd62430902b15586a36093a6679e31b67017397da83b0992f5f816017701"     let sPublicExponent = "010001"    public static func getPrivateKey(smodulus: String, sPrivateExponent: String) -> SecKey? {              let pubExponent: [UInt8] = [1, 0, 1]     let exponent: [UInt8] = sPrivateExponent.hexaBytes     var modulus: [UInt8] = smodulus.hexaBytes           //modulus.insert(0x00, at: 0)           var modulusEncoded: [UInt8] = []     modulusEncoded.append(0x02)     modulusEncoded.append(contentsOf: lengthField(of: modulus))     modulusEncoded.append(contentsOf: modulus)     var exponentEncoded: [UInt8] = []     exponentEncoded.append(0x02)     exponentEncoded.append(contentsOf: lengthField(of: exponent))     exponentEncoded.append(contentsOf: exponent)           var sequenceEncoded: [UInt8] = []     sequenceEncoded.append(0x30)     sequenceEncoded.append(contentsOf: lengthField(of: (modulusEncoded + exponentEncoded)))     sequenceEncoded.append(contentsOf: (modulusEncoded + exponentEncoded))           let keyData = Data(bytes: sequenceEncoded)           // RSA key size is the number of bits of the modulus.     let keySize = (modulus.count * 8)     let attributes: [String: Any] = [       kSecAttrKeyType as String: kSecAttrKeyTypeRSA,       kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,       kSecAttrKeySizeInBits as String: keySize     ]                 let privateKey = SecKeyCreateWithData(keyData as CFData, attributes as CFDictionary, nil)                       return privateKey   }  private static func lengthField(of valueField: [UInt8]) -> [UInt8] {     var count = valueField.count     if count < 128 {       return [ UInt8(count) ]     }     // The number of bytes needed to encode count.     let lengthBytesCount = Int((log2(Double(count)) / 8) + 1)     // The first byte in the length field encoding the number of remaining bytes.     let firstLengthFieldByte = UInt8(128 + lengthBytesCount)     var lengthField: [UInt8] = []     for _ in 0..<lengthBytesCount {       // Take the last 8 bits of count.       let lengthByte = UInt8(count & 0xff)       // Add them to the length field.       lengthField.insert(lengthByte, at: 0)       // Delete the last 8 bits of count.       count = count >> 8     }     // Include the first byte.     lengthField.insert(firstLengthFieldByte, at: 0)     return lengthField   } extension StringProtocol {   var hexaData: Data { .init(hexa) }   var hexaBytes: [UInt8] { .init(hexa) }   private var hexa: UnfoldSequence<UInt8, Index> {     sequence(state: startIndex) { startIndex in       guard startIndex < self.endIndex else { return nil }       let endIndex = self.index(startIndex, offsetBy: 2, limitedBy: self.endIndex) ?? self.endIndex       defer { startIndex = endIndex }       return UInt8(self[startIndex..<endIndex], radix: 16)     }   } }
3
0
1.8k
Feb ’23
Issue creating SecKey type secp256r1 from base64 encoded string
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&lt;CFError&gt;?  var errorPublic: Unmanaged&lt;CFError&gt;?  var error: Unmanaged&lt;CFError&gt;?   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, &amp;errorPublic)!           let privateKey = SecKeyCreateWithData(Data(base64Encoded: privateKeyString)! as NSData, attributesPrivate as NSDictionary, &amp;errorPrivate)!
4
0
1.6k
Jan ’23
p256 signature using cryptokit fails verification on openssl
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.
Replies
3
Boosts
0
Views
1.4k
Activity
Aug ’23
Diffie Hellman Key exchange with .Net Cryptography
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
Replies
2
Boosts
0
Views
1.4k
Activity
Aug ’23
AES-128 CBC Pk5 result differs with Android code
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)
Replies
2
Boosts
0
Views
1.1k
Activity
Aug ’23
Xcode 15 beta Command PhaseScriptExecution failed with a nonzero exit code
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.
Replies
4
Boosts
0
Views
7.6k
Activity
Aug ’23
Deterministic ECDSA algorithm iOS side Implementation.
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. ))
Replies
0
Boosts
0
Views
1k
Activity
Jul ’23
Client certificate using CryptoKit
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?
Replies
4
Boosts
0
Views
1.8k
Activity
Jul ’23
Signature is shown as invalid while creating csr using publicKey and sign csr with private key from Dongle
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*)dong; 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.
Replies
0
Boosts
0
Views
1.2k
Activity
Jun ’23
CryptoKit and Security Framework (ECIES) interoperability
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)}))
Replies
11
Boosts
0
Views
3.8k
Activity
Jun ’23
How to persist SecureEnclave.P256.Signing.PrivateKey
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?
Replies
7
Boosts
0
Views
3.1k
Activity
Jun ’23
[IOS] Swift Cryptokit - P256 ECDSA Signature derRepresentation incompatibility
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
Replies
5
Boosts
0
Views
4.3k
Activity
Jun ’23
Secure enclave with RFC6979
Does the apple secure enclave support secp256r1 with RFC6979? (deterministic ECDSA)
Replies
0
Boosts
0
Views
929
Activity
May ’23
CryptoKit - AES.GCM - How do I encrypt a stream written to disk ( Looking for CipherStream basically)
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?
Replies
1
Boosts
0
Views
1.3k
Activity
Apr ’23
How to detect if OS supports secure enclave?
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?
Replies
6
Boosts
0
Views
2.3k
Activity
Apr ’23
Working with Secure Encalve
I am using DCAppAttestService for attestation , need to perform crypto operations using private key generated during attestation .
Replies
0
Boosts
0
Views
893
Activity
Apr ’23
Best practices for generating a 'Sign In with Apple' nonce on the client
When implementing SiwA on the client, you have the option of passing a nonce to a ASAuthorizationOpenIDRequest (docs). Here's a snippet of the relevant code that could be part of a SiwA implementation: let appleIDProvider = ASAuthorizationAppleIDProvider() let request = appleIDProvider.createRequest() request.requestedScopes = [.fullName, .email] request.nonce = /* What should this look like? */ let authorizationController = ASAuthorizationController(authorizationRequests: [request]) My core question is: are there any restrictions on its length and allowed characters? A similar conversation has been had on this SO post, but I'd like to know if there are any nonce generation implications from a SiwA perspective, as opposed to another auth service provider. The SecRandomCopyBytes docs include the following snippet: var bytes = [Int8](repeating: 0, count: 10) let status = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes) if status == errSecSuccess { // Always test the status. print(bytes) // Prints something different every time you run. } Could the result here be used as a SiwA nonce? Should I instead use the random bytes to index into an alphanumeric array of characters so my nonce contains alphanumerics rather than just numbers? CryptoKit also includes the following API that looks relevant: let nonce = ChaChaPoly.Nonce() The docs say this is a 12-byte nonce– can I throw that in a string and use it? I'd appreciate any clarification on generating nonces for the ASAuthorizationOpenIDRequest API? Thanks!
Replies
0
Boosts
2
Views
1.1k
Activity
Apr ’23
How to generate PEM from Curve25519 public key
I want to use ECC (curve25519) with Diffie-Hellman Key exchange. Backend is using ECC with X9.62 and PKCS#8 encoding. I want to achieve same on iOS so that I can fetch data from backed, decrypt it and show it to user. I tried this code but didn't work func getPEM() -> String { let keyPair = Curve25519.Signing.PrivateKey() let pubKey = keyPair.publicKey let pem = "-----BEGIN PUBLIC KEY-----\(pubKey.rawRepresentation.base64EncodedString())-----END PUBLIC KEY-----" return pem } After searching on Google I found that In order to get PEM we need DER and ASN1 from my public key but they are not supported by CryptoKit. Android is able to get right PEM using bouncycastle. Just for reference I am posting snippet from android code base. import org.bouncycastle.asn1.x9.X9ECParameters import org.bouncycastle.crypto.ec.CustomNamedCurves import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util import org.bouncycastle.jce.provider.BouncyCastleProvider import java.security.* import java.security.spec.ECParameterSpec import java.security.spec.InvalidKeySpecException import java.security.spec.PKCS8EncodedKeySpec import java.security.spec.X509EncodedKeySpec object CryptoKeyGenerator { init { Security.removeProvider(BOUNCY_CASTLE_IDENTIFIER) Security.addProvider(BouncyCastleProvider()) } fun getClientKeyMaterial(): String { val keyPair = generateEphemeralKeyPair() val pemEncodedPublicKey = getPEMEncodedStream(keyPair.public, false) return pemEncodedPublicKey } private fun getPEMEncodedStream(key: Key, privateKey: Boolean): String { val pkcS8EncodedKeySpec = PKCS8EncodedKeySpec(key.encoded) val stringBuilder = StringBuilder() val keyType = if(privateKey) PRIVATE_KEY else PUBLIC_KEY stringBuilder.append(KEY_HEADER_START + keyType + KEY_HEADER_END) stringBuilder.append(CryptoUtils.getBase64Encoded(pkcS8EncodedKeySpec.encoded)) stringBuilder.append(KEY_FOOTER_START + keyType + KEY_HEADER_END) return stringBuilder.toString() } /** * This method generates an ECC KeyPair with Curve25519 specs */ private fun generateEphemeralKeyPair(): KeyPair { val keyPairGenerator = KeyPairGenerator.getInstance(EC_ALGO_IDENTIFIER, BOUNCY_CASTLE_IDENTIFIER) val eccParameters: X9ECParameters = CustomNamedCurves.getByName(ECC_CURVE_SPEC) val eccSpec: ECParameterSpec = EC5Util.convertToSpec(eccParameters) keyPairGenerator.initialize(eccSpec) return keyPairGenerator.generateKeyPair() } } Android generated PEM of public key look like this -----BEGIN PUBLIC KEY-----MIIBMTCB6gYHKoZIzj0CATCB3gIBATArBgcqhkjOPQEBAiB/////////////////////////////////////////7TBEBCAqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqYSRShRAQge0Je0Je0Je0Je0Je0Je0Je0Je0Je0Je0JgtenHcQyGQEQQQqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq0kWiCuGaG4oIa04B7dLHdI0UySPU1+bXxhsinpxaJ+ztPZAiAQAAAAAAAAAAAAAAAAAAAAFN753qL3nNZYEmMaXPXT7QIBCANCAAQwsdIRTVn2+6rlgqAhVvx7ERj/Oku0wHmZZU1OST617h95ygSP5zJOa9lNiKqZMArjtJh7yQ4rg7kUq08Nv8+Q-----END PUBLIC KEY----- Other references: This repo has code for C, Java and nodejs https://github.com/Sahamati/rahasya
Replies
2
Boosts
0
Views
1.1k
Activity
Apr ’23
Cryptokit - How to get PEM representation of Curve25519 Public Key
Hi, How do I generate the pem representation of a curve25519 public key? I can generate the key using :      let privateKey = Curve25519.KeyAgreement.PrivateKey() let publicKey = privateKey.publicKey print(publicKey.rawRepresentation.base64EncodedString()) This prints a string like this : GyQfzi3bLfpDpzi8e9j6lovX15EZY1t1fQQcnJlURxI= But the expected strings are more like : ----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEApxUNh3jHlNSAWE7fadipsh9AjXv6439VY3EWEC5kbgY=\n-----END PUBLIC KEY Even if I add the " -----BEGIN PUBLIC KEY-----" and "-----END PUBLIC KEY-----" tags, it still doesn't process the key. So what format is exactly the base64 encoded string of the raw format of curve25519 public key? And how do I generate the public key pem format? The requirement is for Swift iOS.
Replies
7
Boosts
0
Views
3.4k
Activity
Apr ’23
Can CryptoKit ECDH Public Keys be identity keys?
Hi, I'm using CryptoKit to implement a spec that uses ECDH using P256. The spec says that one should check that the computed shared secret is not all 0x00 bytes. I understand that this can only happen if one of both keys used is the identity point on the curve. Does CryptoKit guarantee that P256.KeyAgreement.PublicKeys can never be the identity point by construction? (as e.g. the Rust elliptic_curve public keys do, according to their documentation)
Replies
4
Boosts
0
Views
1.5k
Activity
Feb ’23
How to create Private SecKey from modulus and private exponent
I am working on an application on IOS and I need to be able to decrypt an element that has been encrypted with a public key, but I only know the modulus and the private exponent of the private key. How can I obtain the private key from these elements in IOS? In java, with the following code I can get the private key from these elements and I can decrypt the element. final RSAPrivateKeySpec privateSpec = new RSAPrivateKeySpec(MODULUS, PRIVATE_EXPONENT); final KeyFactory factory = KeyFactory.getInstance("RSA"); final PrivateKey priv = factory.generatePrivate(privateSpec); On ios, I got the following code, but it doesn't return the private key:      let smodulus = "00c35d6ac32d287dab681c78272931b60ca442bd4505e1b306432af92ef6e07bc3e4e24c2bc2dac69c94753390c3793b80734ef906520a96cafb146ce587ab383e78efc58c5ccf56b5084f3f9bc719e646a0361155ab56b7d71b49f1f90673383ea0fdb4a67900c0973930aa3bc7071c479b4a5d229fcab7ce22b84c1637d7e70b"     let sPrivateExponent = "1f2535700832fc55e73322b49b8ca14942a6a125efda1b805414f5c4d6f6d2c45828fb9bbe64c2651405db42a8e71ae54f7cb7969a5db5cc865aab41ac6f4f77deccb51496fe588f9dcd724a1d49cab96712621afc9c656c56dea011f8ab8e12a321fd62430902b15586a36093a6679e31b67017397da83b0992f5f816017701"     let sPublicExponent = "010001"    public static func getPrivateKey(smodulus: String, sPrivateExponent: String) -> SecKey? {              let pubExponent: [UInt8] = [1, 0, 1]     let exponent: [UInt8] = sPrivateExponent.hexaBytes     var modulus: [UInt8] = smodulus.hexaBytes           //modulus.insert(0x00, at: 0)           var modulusEncoded: [UInt8] = []     modulusEncoded.append(0x02)     modulusEncoded.append(contentsOf: lengthField(of: modulus))     modulusEncoded.append(contentsOf: modulus)     var exponentEncoded: [UInt8] = []     exponentEncoded.append(0x02)     exponentEncoded.append(contentsOf: lengthField(of: exponent))     exponentEncoded.append(contentsOf: exponent)           var sequenceEncoded: [UInt8] = []     sequenceEncoded.append(0x30)     sequenceEncoded.append(contentsOf: lengthField(of: (modulusEncoded + exponentEncoded)))     sequenceEncoded.append(contentsOf: (modulusEncoded + exponentEncoded))           let keyData = Data(bytes: sequenceEncoded)           // RSA key size is the number of bits of the modulus.     let keySize = (modulus.count * 8)     let attributes: [String: Any] = [       kSecAttrKeyType as String: kSecAttrKeyTypeRSA,       kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,       kSecAttrKeySizeInBits as String: keySize     ]                 let privateKey = SecKeyCreateWithData(keyData as CFData, attributes as CFDictionary, nil)                       return privateKey   }  private static func lengthField(of valueField: [UInt8]) -> [UInt8] {     var count = valueField.count     if count < 128 {       return [ UInt8(count) ]     }     // The number of bytes needed to encode count.     let lengthBytesCount = Int((log2(Double(count)) / 8) + 1)     // The first byte in the length field encoding the number of remaining bytes.     let firstLengthFieldByte = UInt8(128 + lengthBytesCount)     var lengthField: [UInt8] = []     for _ in 0..<lengthBytesCount {       // Take the last 8 bits of count.       let lengthByte = UInt8(count & 0xff)       // Add them to the length field.       lengthField.insert(lengthByte, at: 0)       // Delete the last 8 bits of count.       count = count >> 8     }     // Include the first byte.     lengthField.insert(firstLengthFieldByte, at: 0)     return lengthField   } extension StringProtocol {   var hexaData: Data { .init(hexa) }   var hexaBytes: [UInt8] { .init(hexa) }   private var hexa: UnfoldSequence<UInt8, Index> {     sequence(state: startIndex) { startIndex in       guard startIndex < self.endIndex else { return nil }       let endIndex = self.index(startIndex, offsetBy: 2, limitedBy: self.endIndex) ?? self.endIndex       defer { startIndex = endIndex }       return UInt8(self[startIndex..<endIndex], radix: 16)     }   } }
Replies
3
Boosts
0
Views
1.8k
Activity
Feb ’23
Issue creating SecKey type secp256r1 from base64 encoded string
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&lt;CFError&gt;?  var errorPublic: Unmanaged&lt;CFError&gt;?  var error: Unmanaged&lt;CFError&gt;?   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, &amp;errorPublic)!           let privateKey = SecKeyCreateWithData(Data(base64Encoded: privateKeyString)! as NSData, attributesPrivate as NSDictionary, &amp;errorPrivate)!
Replies
4
Boosts
0
Views
1.6k
Activity
Jan ’23