iOS: How to create PKCS12 (P12) keystore from private key and x509certificate in application programmatically?

后端 未结 4 1627
我在风中等你
我在风中等你 2020-12-05 12:39

This question was apparently similar but had no answers of any kind: Programmatically create a x509 certificate for iPhone without using OpenSSL

In our application (

4条回答
  •  余生分开走
    2020-12-05 13:06

    Thank you all very much for this nice solution!

    I translated your code to Swift 3 and built the following function to create a P12 keystore using a signed X509 certificate and a RSA private key, both in PEM format:

    func createP12(pemCertificate: String, pemPrivateKey: String) {
        // Read certificate
        let buffer = BIO_new(BIO_s_mem())
        pemCertificate.data(using: .utf8)!.withUnsafeBytes({ (bytes: UnsafePointer) -> Void in
            BIO_puts(buffer, bytes)
        })
        let certificate = PEM_read_bio_X509(buffer, nil, nil, nil)
        X509_print_fp(stdout, certificate)
        // Read private key
        let privateKeyBuffer = BIO_new(BIO_s_mem())
        pemPrivateKey.data(using: .utf8)!.withUnsafeBytes({ (bytes: UnsafePointer) -> Void in
            BIO_puts(privateKeyBuffer, bytes)
        })
        let privateKey = PEM_read_bio_PrivateKey(privateKeyBuffer, nil, nil, nil)
        PEM_write_PrivateKey(stdout, privateKey, nil, nil, 0, nil, nil)
        // Check if private key matches certificate
        guard X509_check_private_key(certificate, privateKey) == 1 else {
            NSLog("Private key does not match certificate")
            return
        }
        // Set OpenSSL parameters
        OPENSSL_add_all_algorithms_noconf()
        ERR_load_crypto_strings()
        // Create P12 keystore
        let passPhrase = UnsafeMutablePointer(mutating: ("" as NSString).utf8String)
        let name = UnsafeMutablePointer(mutating: ("SSL Certificate" as NSString).utf8String)
        guard let p12 = PKCS12_create(passPhrase, name, privateKey, certificate, nil, 0, 0, 0, 0, 0) else {
            NSLog("Cannot create P12 keystore:")
            ERR_print_errors_fp(stderr)
            return
        }
        // Save P12 keystore
        let fileManager = FileManager.default
        let tempDirectory = NSTemporaryDirectory() as NSString
        let path = tempDirectory.appendingPathComponent("ssl.p12")
        fileManager.createFile(atPath: path, contents: nil, attributes: nil)
        guard let fileHandle = FileHandle(forWritingAtPath: path) else {
            NSLog("Cannot open file handle: \(path)")
            return
        }
        let p12File = fdopen(fileHandle.fileDescriptor, "w")
        i2d_PKCS12_fp(p12File, p12)
        fclose(p12File)
        fileHandle.closeFile()
    }
    

    EDIT:

    OpenSSL can be used in iOS with the OpenSSL-for-iPhone project:

    1. Check out the repository
    2. Build the static libraries with ./build-libssl.sh
    3. Add $(YOUR_PATH)/OpenSSL-for-iPhone/include to header search paths
    4. Add $(YOUR_PATH)/OpenSSL-for-iPhone/lib to library search paths
    5. Add libcrypto.a and libssl.a to linked frameworks and libraries
    6. Add the following headers to the bridging header:

    Project-Bridging-Header.h:

    #import 
    #import 
    #import 
    #import 
    

提交回复
热议问题