2014-09-24 4 views
1

Как реализовать эффект следующей команды в Objective-C?Извлечь открытый ключ из частного ключа в формате pem

openssl rsa -in mykey.pem -pubout > mykey.pub 

Я могу сгенерировать закрытый ключ в формате pem.

Вот код, который я использую, чтобы прочитать закрытый ключ в RSS-объекте openssl.

BIO* bpPrivate = nil; 
NSString *filePath = ..... 
const char *path = [filePath UTF8String]; 
bpPrivate = BIO_new_file(path, "r"); 
_rsa = PEM_read_bio_RSAPrivateKey(bpPrivate, NULL, 0, NULL); 

Я хочу извлечь открытый ключ из секретного ключа.

+0

Objective-C потребляет регулярные C, так его ОК, чтобы использовать что-либо написанное против C. Вам не нужно ограничивать себя классами Objective-C. Фактически, вы не ограничиваете себя, вызывая OpenSSL 'PEM_read_bio_RSAPrivateKey'. – jww

ответ

0

В памяти нет понятия ASN.1, DER, PEM или других кодировок. Ключ RSA использует ту же структуру как для открытого, так и для частного ключа. Для открытого ключа некоторые поля не используются. Если вас интересуют эти поля, посетите PKCS #1 или RFC 3447.

Так что, учитывая RSA*, все, что вам нужно сделать, это позвонить PEM_write_bio_RSAPublicKey (даже с закрытым ключом). Вы также можете использовать PEM_write_RSAPublicKey (даже с закрытым ключом). См. pem(3) для всех функций чтения и записи.

Вы также можете совершить долгий путь в RSAPublicKey_dup. Он примет ключ priavte (т. Е. RSA*) и возвращает открытый ключ (то есть, RSA*). Но это своего рода ненужный шаг по большей части. Возможно, было бы полезно сохранить ключ в памяти, если у вас есть это требование.

RSA* privKey = NULL; 
RSA* pubKey = NULL; 
BIGNUM* exp = NULL; 

privKey = RSA_new(); 
ASSERT(privKey != NULL); 

exp = BN_new(); 
ASSERT(exp != NULL); 

rc = BN_set_word(exp, RSA_F4); 
ASSERT(rc == 1); 

rc = RSA_generate_key_ex(privKey, 1024, exp, NULL); 
ASSERT(rc == 1); 

pubKey = RSAPublicKey_dup(privKey); 
ASSERT(pubKey != NULL); 

RSA_print_fp(stdout, pubKey, 0); 

if(pubKey) { 
    RSA_free(pubKey); 
} 

if(privKey) { 
    RSA_free(privKey); 
} 

if(exp) { 
    BN_free(exp); 
} 

В RSA_print_fp приводит:

$ ./t.exe 
Public-Key: (1024 bit) 
Modulus: 
    00:c3:30:67:d9:11:59:9b:85:7a:1a:95:fa:fd:c0: 
    dd:cd:21:d6:41:6b:16:70:c2:57:9a:f2:d2:bd:3b: 
    c0:02:7b:6a:ab:7f:13:a7:53:2f:31:10:08:3a:62: 
    28:40:5f:82:19:23:f6:0f:78:f5:e3:e4:19:a1:b4: 
    73:65:35:10:db:17:28:41:42:ba:df:8c:18:3b:d8: 
    62:52:65:61:0e:cd:60:28:c9:75:a8:5b:46:a4:89: 
    db:78:89:49:87:5d:7f:ce:d0:44:c4:fd:4a:74:66: 
    d4:46:21:c1:89:97:28:de:43:e9:94:50:f1:36:85: 
    a7:ef:6c:6d:6f:5d:78:00:67 
Exponent: 65537 (0x10001) 

Вы можете добавить вызов PEM_write_RSAPublicKey:

FILE* file = fopen("rsa-pub.pem", "w"); 
ASSERT(file != NULL); 

rc = PEM_write_RSAPublicKey(file, pubKey); 

Тогда:

$ ./t.exe 
$ cat rsa-pub.pem 
-----BEGIN RSA PUBLIC KEY----- 
MIGJAoGBAMb2jIVcTttHRqG9szv3CFZ742l7LxnVoM6oOfQXNOwabh+GB4Srf4IA 
XRcGan7cj1DShnoPw9fp3IeuAUerk3xz8yPXCw09dLwrFcsmItLVnSLoRtpHnxN5 
30Wd5vKpvKTLIQnurGo05s911ukFJeGo2y2OjSnTiQcJLUdt497tAgMBAAE= 
-----END RSA PUBLIC KEY----- 
+0

Спасибо, что работает, как я ожидаю. RSAPublicKey_dup решает мою проблему. – yohon

+0

@yohon Можем ли мы создать сертификат PEM с кривой Eliptice «ecdsa-with-SHA256» «http://oid-info.com/cgi-bin/display?oid=1.2.840.10045.4.3.2&action=display»? – Aleem

+0

@ oid-info.com/cgi-bin - см. [Эллиптическая кривая кривых] (https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography) в вики OpenSSL. – jww