I having problems with finding a common crypto as the decrypted string is null
You keep asking new CommonCrypto questions but you never answer any of the questions that I ask )-: Let’s start with the big one: in your intended crypto design, how do the client app and the PHP code agree on the key to use for this symmetric cypher?
If i switch to HTTPS and use the following code. Will the data that is being send from the client- OSX App to the PHP Web Service via POST be Secure (Encrypted)?
I’m not sure I understand your question here. It seems like you’re asking “Will an HTTPS request be encrypted?”, in which case the answer is clearly “Yes.” The S stands for Secure after all.
A vanilla HTTPS request will not give you end-to-end security, that is, a debugging HTTP proxy could still see your traffic. To prevent that you’ll have to implement some sort of credential pinning (either certificate pinning or public key pinning). Pasted in below are examples of both.
IMPORTANT Credential pinning has its drawbacks. For example:
Your app will not work in certain enterprise HTTP proxy environments, which use the same technique as a debugging HTTP proxy to see inside HTTPS connections.
If you change the credential on your server, you’ll have to change your app to match.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
func didReceive(serverTrustChallenge challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
let expectedCer = Bundle.main.certificate(named: "IETF")
let trust = challenge.protectionSpace.serverTrust!
if trust.evaluatePinnedTo(serverKey: expectedCer) {
completionHandler(.performDefaultHandling, nil)
} else {
completionHandler(.cancelAuthenticationChallenge, nil)
}
}
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
// Look for specific authentication challenges and dispatch those to various helper methods.
//
// IMPORTANT: It's critical that, if you get a challenge you weren't expecting,
// you resolve that challenge with `.performDefaultHandling`.
switch (challenge.protectionSpace.authenticationMethod, challenge.protectionSpace.host) {
case (NSURLAuthenticationMethodServerTrust, "www.ietf.org"):
self.didReceive(serverTrustChallenge: challenge, completionHandler: completionHandler)
default:
completionHandler(.performDefaultHandling, nil)
}
}
func didReceive(serverTrustChallenge challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
let expectedCer = Bundle.main.certificate(named: "Example")
let trust = challenge.protectionSpace.serverTrust!
if trust.evaluatePinnedTo(serverCertificate: expectedCer) {
completionHandler(.performDefaultHandling, nil)
} else {
completionHandler(.cancelAuthenticationChallenge, nil)
}
}
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
// Look for specific authentication challenges and dispatch those to various helper methods.
//
// IMPORTANT: It's critical that, if you get a challenge you weren't expecting,
// you resolve that challenge with `.performDefaultHandling`.
switch (challenge.protectionSpace.authenticationMethod, challenge.protectionSpace.host) {
case (NSURLAuthenticationMethodServerTrust, "example.com"):
self.didReceive(serverTrustChallenge: challenge, completionHandler: completionHandler)
default:
completionHandler(.performDefaultHandling, nil)
}
}
import Foundation
extension SecTrust {
func evaluate() -> Bool {
var trustResult: SecTrustResultType = .invalid
let err = SecTrustEvaluate(self, &trustResult)
guard err == errSecSuccess else { return false }
return [.proceed, .unspecified].contains(trustResult)
}
func evaluatePinnedTo(serverCertificate expectedCer: SecCertificate) -> Bool {
// Do an actual trust evaluation. This is necessary in order to get meaningful
// results from `SecTrustGetCertificateAtIndex` and, if we're going to do it
// anyway, we may as well pay attention to its result.
guard self.evaluate() else {
return false
}
// Compare the certificate from the trust evaluation to our expected certificate.
guard let actualCer = SecTrustGetCertificateAtIndex(self, 0) else { return false }
if CFEqual(actualCer, expectedCer) {
return true
} else {
return false
}
}
func evaluatePinnedTo(serverKey expectedCer: SecCertificate) -> Bool {
func publicKey(from certificate: SecCertificate) -> SecKey? {
var tOpt: SecTrust? = nil
let err = SecTrustCreateWithCertificates([certificate] as CFArray, SecPolicyCreateBasicX509(), &tOpt)
guard err == errSecSuccess else { return nil }
let t = tOpt!
var trustResult: SecTrustResultType = .invalid
_ = SecTrustEvaluate(t, &trustResult)
return SecTrustCopyPublicKey(t)
}
// Do a default trust evaluation, just to be sure.
guard self.evaluate() else {
return false
}
// Load the expected public key from the server certificate we're given.
guard let expectedPublicKey = publicKey(from: expectedCer) else { return false }
// Compare the public key from the trust evaluation to our expected certificate.
guard let actualPublicKey = SecTrustCopyPublicKey(self) else { return false }
if CFEqual(actualPublicKey, expectedPublicKey) {
return true
} else {
return false
}
}
}