2017-04-19 2 views
5

나는 SecKeyGeneratePair과 함께 공개/개인 키 쌍 (Elliptic Curve)을 만들었습니다.OpenSSL을 사용하여 SecKey에서 CSR 생성

SecKey 인스턴스를 사용하여 Swift에서 OpenSSL을 사용하여 CSR을 생성하려면 어떻게해야합니까?

+1

[관련 정보] (https://stackoverflow.com/questions/13456237/generating-an-openssl-certificate-signing-request-in-ios-with-keychain-stored-ke?rq=1) 빠른. –

답변

1

Apple 자체 보안 프레임 워크에는 현재 공개 된 API가 없거나 CSR을 생성하지 못한다고 말할 수 있습니다. 그것은 기술적으로 OpenSSL을 감쌌습니다. 그래서 당신이 OpenSSL을 가지고 있다면 (나는 개인적으로 LibreSSL을 선호한다. libtls은 삶을 편하게 해준다). 내 대답은 적용되지 않지만 많은 많은 예

그래서이 작업을 수행하는 방법을 찾는 단계를 통해 갈 수 거기 밖으로 당신은 또한 Commoncrypto를 사용할 수있는 대안으로

. OpenSSL으로 작업하는 가장 쉬운 방법은 설명서를 완전히 무시하고 곧바로 열람 소스로 이동하는 것입니다.

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

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

중요 참고 :하십시오 보안 곡선을 ​​선택해야합니다 우리가 필요로하는 무엇을 달성하기

, 우리는 '복제'다음이 명령에 필요합니다. openssl ecparam -list_curves를 사용하여 openssl 버전에서 지원되는 커브 목록을 가져옵니다. 키

ecparam은 우리가 처음 sslsource/응용 프로그램 /하려면 openssl/ecparam.c에서 볼 필요가 우리에게 알려줍니다 생성 Read more

1 단계.

소스는 우리에게 3 단계를 제공합니다 : 글쓴이, 그룹 매개 변수 설정 및 최종 키 생성을 위해 BIO를 설정하십시오. 나는 원유를 만들려면이 방법을 사용 req.c

에 사용되는 일부 상용구 코드를 포함하는 CSR 같은 원칙에 따라

하지만 req.c에서 찾고이 시간과 apps.c에서 일부 코드를 생성

2 단계 swift에서 실행되는 개념 증명 작업은 여기에서 github에서 확인할 수 있습니다. CertificateTool 코드는 swift4 + toolchain과 일부 버전의 openSSL을 컴파일 할 수있는 시스템에서 실행됩니다. 이 코드는 어떤 BIO 관련 기능을 포함하지 않는

// 
// 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) 
    } 
} 

(: 서명 요청을 생성

// 
// 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) 
    } 
} 

:

편집 : EC 비밀 키를 생성

아직까지는) PEM 데이터를 파일이나 데이터 버퍼에 쓰지 만 정말 쉽게 추가 할 수 있습니다.

면책 조항 : 저는 전문적인 암호 작성자가 아니며 OpenSSL API의 모든 기능과 장점을 알고 있습니다. 내가 제공 한 코드가 100 % 올바른 구현임을 보장 할 수는 없습니다. 웹에서 다운로드 한 코드, 특히 암호 코드를 항상 조심하십시오.