importFoundationimportSecuritystructMastgTest{staticfuncmastgTest(completion:@escaping(String)->Void){//Step1:GenerateanRSAkeypairwitha1024-bitkeysizelettag="org.owasp.mas.rsa-1014".data(using:.utf8)!letkeyAttributes:[String:Any]=[kSecAttrKeyTypeasString:kSecAttrKeyTypeRSA,kSecAttrKeySizeInBitsasString:1024,//Using1024-bitRSAkeykSecPrivateKeyAttrsasString:[kSecAttrIsPermanentasString:true,//tostoreitintheKeychainkSecAttrApplicationTagasString:tag]//tofindandretrieveitfromtheKeychainlater]varerror:Unmanaged<CFError>?guardletprivateKey=SecKeyCreateRandomKey(keyAttributesasCFDictionary,&error)else{completion("Failed to generate private key: \(String(describing: error))")return}guardletpublicKey=SecKeyCopyPublicKey(privateKey)else{completion("Failed to generate public key")return}//Converttheprivatekeytodata(DERformat)guardletprivateKeyData=SecKeyCopyExternalRepresentation(privateKey,&error)asData?else{completion("Failed to extract private key: \(String(describing: error))")return}//Encodetheprivatekeyfordisplay//letprivateKeyBase64=privateKeyData.base64EncodedString()letprivateKeyHex=privateKeyData.map{String(format:"%02hhx",$0)}.joined()//Convertthepublickeytodata(DERformat)guardletpublicKeyData=SecKeyCopyExternalRepresentation(publicKey,&error)asData?else{completion("Failed to extract public key: \(String(describing: error))")return}//Encodethepublickeyfordisplay//letpublicKeyBase64=publicKeyData.base64EncodedString()letpublicKeyHex=publicKeyData.map{String(format:"%02hhx",$0)}.joined()//DatatosignletdataToSign="This is a sample text".data(using:.utf8)!//Step2:Signthedatawiththeprivatekeyguardletsignature=SecKeyCreateSignature(privateKey,SecKeyAlgorithm.rsaSignatureMessagePKCS1v15SHA256,dataToSignasCFData,&error)else{completion("Signing failed: \(String(describing: error))")return}//ConvertsignaturetohexstringfordisplayletsignatureHex=(signatureasData).map{String(format:"%02hhx",$0)}.joined()//Step3:VerifythesignaturewiththepublickeyletverificationStatus=SecKeyVerifySignature(publicKey,SecKeyAlgorithm.rsaSignatureMessagePKCS1v15SHA256,dataToSignasCFData,signatureasCFData,&error)letverificationResult=verificationStatus?"Signature is valid.":"Signature is invalid."letvalue=""" Original: \(String(data: dataToSign, encoding: .utf8)!) Private Key (Hex): \(privateKeyHex) Public Key (Hex): \(publicKeyHex) Signature (Hex): \(signatureHex) Verification: \(verificationResult) """completion(value)}}
This function is pretty big so we just included the relevant part of the code that's right before the call to SecKeyCreateRandomKey. Note that we can see attributes being set in the parameters dictionary such as kSecAttrKeySizeInBits as reloc.kSecAttrKeySizeInBits. In radare2, this means that the symbol kSecAttrKeySizeInBits is not directly referenced by an absolute address but rather through a relocation entry. This entry will be resolved by the dynamic linker at runtime to the actual address where kSecAttrKeySizeInBits is located in memory.
In the output we can see how the kSecAttrKeySizeInBits attribute is set to 1024 bits (0x400 in hexadecimal) using the x8 register. This is later used to call SecKeyCreateRandomKey.
The test fails because the key size is set to 1024 bits, which is considered weak for RSA encryption. The key size should be increased to 2048 bits or higher to provide adequate security against modern cryptographic attacks.