2016-12-14 57 views
0

私はCSRを作成する必要があるアプリで、目的のCまたはSwiftを使用して簡単にはできません。そこで、私はOpenSSLを選択してCSRを作成しましたが、コードを正常に作成できましたが、もう一つの重要な要件はセキュアな領域に鍵を格納することですが、OpenSSLではこれをオンラインで検索すると不可能です。 ここでは、セキュリティ保護されたエンクレーブ内のオブジェクトcで鍵ペアを作成し、公開鍵(データ付き)と秘密鍵(参照付き)をopenSSL(EC_KEY)にエクスポートしてからCSRを作成します。私は鍵をエクスポートするにはthis linkを見つけましたが、秘密鍵をエクスポートする方法はありません(データではできませんが、参照あり)。公開鍵と秘密鍵をiOSからOpenSSLにエクスポート

私はそれを行う方法をいくつか指導が必要です。

- (void)genCSRX509ForEC 
{ 
    int    ret = 0; 
    DSA    *r = NULL; 
    BIGNUM   *bne = NULL; 


int    nVersion = 1; 

unsigned long e = RSA_F4; 

X509_REQ  *x509_req = NULL; 
X509_NAME  *x509_name = NULL; 
EVP_PKEY  *pKey = NULL; 
BIO    *out = NULL; 

const char  *szCountry = "USA"; 
const char  *szProvince = "MA"; 
const char  *szCity = "Boston"; 
const char  *szOrganization = "MyComp"; 
const char  *szCommon = "MYC"; 

const char  *szPath = "x509Req.pem"; 

// 1. generate rsa key 
bne = BN_new(); 
ret = BN_set_word(bne,e); 
if(ret != 1){ 
    goto free_all; 
} 

r = DSA_new(); 
//  
// EC_KEY* _ec_key = EC_KEY_new(); 
// EC_GROUP* ec_group_new = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); 
// const EC_GROUP* ec_group = ec_group_new; 
// if (!EC_KEY_set_group(_ec_key,ec_group)) 
//  NSLog(@"Error in initializeCrypto, EC_KEY_set_group failed!"); 

    // Segfault at this position 


    //////////////////////////// CREATE KEYPAIR ///////////////////////////////////// 

    EC_KEY* _ec_key = EC_KEY_new(); 
    EC_GROUP* ec_group_new = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); 
    const EC_GROUP* ec_group = ec_group_new; 
    if (!EC_KEY_set_group(_ec_key,ec_group)) 
     NSLog(@"Error in initializeCrypto, EC_KEY_set_group failed!"); 

    EC_KEY_generate_key(_ec_key); 

    ret = EC_KEY_check_key(_ec_key); 
    if (ret != 1){ 
     goto free_all; 
    } 

     const BIGNUM *privateKey = EC_KEY_get0_private_key(_ec_key); 
     const EC_POINT *publicKey = EC_KEY_get0_public_key(_ec_key); 

     privateKeySize = i2d_ECPrivateKey(_ec_key,NULL); 
     unsigned char *privateKeyBuf = OPENSSL_malloc(privateKeySize); 
     memset(privateKeyBuf, 0, privateKeySize); 
     int status = i2d_ECPrivateKey(_ec_key,&privateKeyBuf); 
     if (!ret){ 
     NSLog(@"Private key to DER failed\n"); 
     return; 
     } 
     else { 
     NSLog(@"Private key %s",privateKeyBuf); 
     } 
    privateKeyUnsignedChar = privateKeyBuf; 

     publicKeySize = i2o_ECPublicKey(_ec_key,NULL); 
     unsigned char *publicKeyBuf = OPENSSL_malloc(privateKeySize); 
     memset(publicKeyBuf, 0, privateKeySize); 
     ret = i2o_ECPublicKey(_ec_key,&publicKeyBuf); 
     if (!ret){ 
     NSLog(@"Public key to octed failed\n"); 
     return; 
     } 
     else { 
     NSLog(@"Public key %s",publicKeyBuf); 
     } 
    publicKeyUnsignedChar = publicKeyBuf; 
    NSLog(@"key generation generated"); 

    //////////////////////////// CREATE KEYPAIR END ///////////////////////////////////// 


    // 2. set version of x509 req 
    x509_req = X509_REQ_new(); 
    ret = X509_REQ_set_version(x509_req, nVersion); 
    if (ret != 1){ 
     goto free_all; 
    } 

    // 3. set subject of x509 req 
    x509_name = X509_REQ_get_subject_name(x509_req); 

    ret = X509_NAME_add_entry_by_txt(x509_name,"C", MBSTRING_ASC, (const unsigned char*)szCountry, -1, -1, 0); 
    if (ret != 1){ 
     goto free_all; 
    } 

    ret = X509_NAME_add_entry_by_txt(x509_name,"ST", MBSTRING_ASC, (const unsigned char*)szProvince, -1, -1, 0); 
    if (ret != 1){ 
     goto free_all; 
    } 

    ret = X509_NAME_add_entry_by_txt(x509_name,"L", MBSTRING_ASC, (const unsigned char*)szCity, -1, -1, 0); 
    if (ret != 1){ 
     goto free_all; 
    } 

    ret = X509_NAME_add_entry_by_txt(x509_name,"O", MBSTRING_ASC, (const unsigned char*)szOrganization, -1, -1, 0); 
    if (ret != 1){ 
     goto free_all; 
    } 

    ret = X509_NAME_add_entry_by_txt(x509_name,"CN", MBSTRING_ASC, (const unsigned char*)szCommon, -1, -1, 0); 
    if (ret != 1){ 
     goto free_all; 
    } 

    // 4. set public key of x509 req 
    pKey = EVP_PKEY_new(); 
    EVP_PKEY_assign_EC_KEY(pKey, _ec_key); 
    r = NULL; // will be free rsa when EVP_PKEY_free(pKey) 

    ret = X509_REQ_set_pubkey(x509_req, pKey); 
    if (ret != 1){ 
     goto free_all; 
    } 

    // 5. set sign key of x509 req 
    ret = X509_REQ_sign(x509_req, pKey, EVP_sha256()); // return x509_req->signature->length 
    if (ret <= 0){ 
     goto free_all; 
    } 

    out = BIO_new_file(szPath,"w"); 
    ret = PEM_write_bio_X509_REQ(out, x509_req); 
    X509_REQ_print_fp(stdout, x509_req); 


    [self createFileForPEM:x509_req]; 

    // PEM_write_X509_REQ(pemFile, certSigningRequest); 
    // 6. free 
free_all: 
    X509_REQ_free(x509_req); 
    BIO_free_all(out); 

    EVP_PKEY_free(pKey); 
// BN_free(bne); 


} 
+0

相互運用性のためには、そのキーに 'OPENSSL_EC_NAMED_CURVE'フラグも設定する必要があります。また、[Elliptic Curve Cryptography | OpenSSL wikiの「Named Curves」(https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography#Named_Curves)を参照してください。 – jww

+0

@jwwこれにより、OpenSSLから生成された鍵と対話できますが、この "kSecAttrTokenIDSecureEnclave"を使用して目的のcで行っている安全なエンクレーブに秘密鍵を格納するにはどうすればよいですか?これはOpenSSLを使用して可能です – Aleem

答えて

0

は、あなたが与えられたunsigned char配列にDERフォーマットに変換するi2d_ECPrivateKeyを呼び出してから、Base64でに変換し、ファイルに書き込むことができhttps://www.openssl.org/docs/man1.0.2/crypto/d2i_ECPrivate_key.htmlhttps://www.openssl.org/docs/man1.0.2/crypto/d2i_ECPrivateKey.html

を参照してください。

//int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); 
int len = -1; 
unsigned char outbuf[2000]; /*large enough to hold the key.*/ 
len = i2d_ECPrivateKey(_ec_key, outbuf); 
/*Now, you have outbuf with len bytes*/ 
/*Write it to file with in DER format and you can use d2i_ECPrivateKey to import it. */ 
関連する問題