如何向设备添加自签名根证书颁发机构?

时间:2015-05-26 21:10:33

标签: ios swift certificate

如何在设备上安装根证书颁发机构?

只有我的应用才需要证书,并且如果可能,可以将其安装在沙箱中。

它适用于drag the certificate onto the simulator and install it,但未使用以下代码:

let rootCertPath = NSBundle.mainBundle().pathForResource("server", ofType: "der")!
let rootCertData = NSData(contentsOfFile: rootCertPath)!
let rootCert     = SecCertificateCreateWithData(kCFAllocatorDefault, rootCertData).takeRetainedValue()

let error = SecItemAdd(
[
    NSString(format: kSecClass):    NSString(format: kSecClassCertificate),
    NSString(format: kSecValueRef): rootCert
], nil)

SecItemAdd返回没有错误,似乎正确安装在设备上,但仍然无法连接到服务器并出现错误:

  

NSURLConnection / CFURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9813)

连接服务器的代码:

let request = NSURLRequest(URL: NSURL(string: "https://" + server + ":" + port)!)
let session = NSURLSession(configuration: .defaultSessionConfiguration())

session.dataTaskWithRequest(request, completionHandler:
{(data, response, error) in
    println(error)
}).resume()

error打印以下内容:

  

错误域= NSURLErrorDomain代码= -1202"此服务器的证书无效。

但是,如果我在模拟器的配置文件中手动安装相同的证书,它就可以正常连接。

1 个答案:

答案 0 :(得分:1)

这不安全,不需要证书

使用套接字(NSStream和CFStream)进行管理以使其正常工作。

需要注意的重要一点是,我需要禁用kCFStreamSSLValidatesCertificateChain才能使我的证书正常工作。

class Authentication: NSObject, NSStreamDelegate
{
    private var  inputStream: NSInputStream?
    private var outputStream: NSOutputStream?

    func connectToServer(server: String, port: Int)
    {   
        let sslSettings =
        [
            NSString(format: kCFStreamSSLValidatesCertificateChain): kCFBooleanFalse
        ]

        NSStream.getStreamsToHostWithName(server, port: port, inputStream: &inputStream, outputStream: &outputStream)

        CFReadStreamSetProperty(inputStream, kCFStreamPropertySocketSecurityLevel, kCFStreamSocketSecurityLevelTLSv1)
        CFReadStreamSetProperty(inputStream, kCFStreamPropertySSLSettings, sslSettings)

         inputStream!.delegate = self
        outputStream!.delegate = self

         inputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
        outputStream!.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)

         inputStream!.open()
        outputStream!.open()
    }
}

有用的链接:

iOS: Pre install SSL certificate in keychain - programmatically

Overriding TLS Chain Validation Correctly

HTTPS Server Trust Evaluation

SSL Socket connection iOS

Toll-free bridging and pointer access in Swift

Adding a self-signed certificate to iphone Simulator?