2017-04-19 15 views
5

Tôi đã tạo cặp khóa công khai/riêng tư (Đường cong Elliptic) với SecKeyGeneratePair.Tạo CSR từ SecKey bằng OpenSSL

Làm cách nào tôi có thể sử dụng các trường hợp SecKey để tạo CSR bằng OpenSSL trong Swift?

+1

[Liên quan] (https://stackoverflow.com/questions/13456237/generating-an-openssl-certificate-signing-request-in-ios-with-keychain-stored-ke?rq=1) nhưng không ở Nhanh. –

Trả lời

1

Theo như tôi có thể nói, khung bảo mật của riêng Apple không có API hiện đang được tiếp xúc với f hoặc tạo CSR. Đó là kỹ thuật OpenSSL bọc; vì vậy trong trường hợp bạn có OpenSSL (cá nhân tôi thích LibreSSL, libtls làm cho cuộc sống trở nên dễ dàng).

Là một thay thế bạn cũng có thể sử dụng Commoncrypto, mà câu trả lời của tôi sẽ không bao gồm nhưng có rất nhiều rất nhiều ví dụ ra có

Vì vậy, cho phép đi qua các bước tìm hiểu làm thế nào để làm điều này. Tôi thấy rằng cách dễ nhất để làm việc với OpenSSL là bỏ qua tài liệu hoàn toàn và chuyển thẳng đến nguồn đọc.

Để đạt được những gì chúng ta cần, chúng ta cần phải 'lặp lại' 2 lệnh sau:

openssl ecparam -out server.key -name prime256v1 -genkey

openssl req -new -key server.key -out server.csr

Chú ý quan trọng: Hãy chắc chắn để chọn một an toàn đường cong. Sử dụng openssl ecparam -list_curves để nhận danh sách các đường cong được hỗ trợ bởi phiên bản openssl của bạn. Read more

Bước 1 Tạo phím

ecparam cho chúng ta biết chúng ta phải nhìn vào sslsource/apps/openssl/ecparam.c đầu tiên.

Nguồn cung cấp cho chúng tôi 3 bước: Thiết lập BIO để viết, thiết lập thông số nhóm và cuối cùng tạo khóa.

Bước 2 Tạo CSR

Tiếp theo nguyên tắc tương tự nhưng lần này nhìn vào req.c và một số mã trong apps.c trong đó có một số mã soạn sẵn được sử dụng trong req.c

tôi đã sử dụng phương pháp này để tạo ra một thô nhưng bằng chứng làm việc của khái niệm chạy nhanh, bạn có thể kiểm tra nó trên github ở đây: CertificateTool Mã sẽ chạy trên bất kỳ hệ thống nào bạn có thể biên dịch swift4 + toolchain trên và một số phiên bản openSSL.

Edit:

Tạo phím EC bí mật:

// 
// ECKey.swift 
// CertificateToolPackageDescription 
// 
// Created by Antwan van Houdt on 10/01/2018. 
// 
import CLibreSSL 

public class ECKey { 
    internal let secretKey: OpaquePointer 
    private let group: OpaquePointer 

    public init() { 
     group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1) 
     EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE) 
     EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_COMPRESSED) 

     secretKey = EC_KEY_new() 
     EC_KEY_set_group(secretKey, group) 
     EC_KEY_generate_key(secretKey) 
    } 

    deinit { 
     EC_KEY_free(secretKey) 
     EC_GROUP_free(group) 
    } 
} 

Tạo yêu cầu ký:

// 
// CertificateRequest.swift 
// CertificateToolPackageDescription 
// 
// Created by Antwan van Houdt on 10/01/2018. 
// 
import CLibreSSL 

public enum NIDType: String { 
    case email = "emailAddress" 
    case hostName = "CN" 
    case organizationalUnit = "OU" 
    case organization  = "O" 
    case city  = "L" 
    case state  = "ST" 
    case countryCode = "C" 
} 

public class CertificateSigningRequest { 
    private let request: UnsafeMutablePointer<X509_REQ> 
    private let key:  ECKey 
    private let name: UnsafeMutablePointer<X509_NAME> 

    public init(key: ECKey, email: String, hostName: String, organizationalUnit: String, organization: String, countryCode: String, state: String, city: String) { 
     request = X509_REQ_new() 
     self.key = key 

     name = X509_NAME_new() 
     X509_REQ_set_version(request, 2) 

     self.add(name: email, type: .email) 
     self.add(name: hostName, type: .hostName) 
     self.add(name: organizationalUnit, type: .organizationalUnit) 
     self.add(name: organization, type: .organization) 
     self.add(name: countryCode, type: .countryCode) 
     self.add(name: city, type: .city) 
     self.add(name: state, type: .state) 

     X509_REQ_set_subject_name(request, name) 

     self.setPublicKey() 
    } 

    deinit { 
     X509_REQ_free(request) 
     X509_NAME_free(name) 
    } 

    private func add(name: String, type: NIDType) { 
     var buff = Array(name.utf8) 
     X509_NAME_add_entry_by_NID(self.name, OBJ_txt2nid(type.rawValue), MBSTRING_UTF8, &buff, Int32(buff.count), 0, 0) 
    } 

    private func setPublicKey() { 
     let certKey = EVP_PKEY_new() 
     EVP_PKEY_set1_EC_KEY(certKey, key.secretKey) 

     X509_REQ_set_pubkey(request, certKey) 
     X509_REQ_sign(request, certKey, EVP_sha256()) 

     EVP_PKEY_free(certKey) 
    } 
} 

Note Mã này không chứa bất kỳ chức năng BIO liên quan (chưa) để ghi dữ liệu PEM vào một tệp hoặc một bộ đệm dữ liệu, nhưng chúng thực sự dễ dàng để thêm.

Tuyên bố từ chối trách nhiệm: Tôi không phải là chuyên gia mật mã chuyên nghiệp cũng như không biết tất cả các thông tin chi tiết về API OpenSSL. Tôi không thể đảm bảo rằng mã tôi đã cung cấp là bản thực thi chính xác 100%. Luôn cảnh giác với mã, đặc biệt là mã crypto, được tải xuống từ web.

Các vấn đề liên quan