2012-04-18 13 views
7

He creado un par de claves usando SecKeyGeneratePair. Ahora me gustaría pasar la clave pública a un servidor, pero no estoy muy seguro de cómo proceder.iPhone: ¿Cómo exportas un SecKeyRef o un NSData que contiene claves públicas al formato PEM?

Tengo una función getPublicKeyBits (tomada de Apple CryptoExercise), pero realmente no sé qué hacer con NSData en bruto. Esta es la función:

- (NSData *)getPublicKeyBits { 
    OSStatus sanityCheck = noErr; 
    NSData* publicKeyBits = nil; 
    NSData* publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)]; 
    CFDataRef cfresult = NULL; 


    NSMutableDictionary * queryPublicKey = [[NSMutableDictionary alloc] init]; 

    // Set the public key query dictionary. 
    [queryPublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass]; 
    [queryPublicKey setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag]; 
    [queryPublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; 
    [queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnData]; 

    // Get the key bits. 
    sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)queryPublicKey, (CFTypeRef*)&cfresult); 


    if (sanityCheck != noErr) 
    { 
     publicKeyBits = nil; 
    } 
    else 
    { 
     publicKeyBits = (__bridge_transfer NSData *)cfresult; 
    } 

    return publicKeyBits; 
} 

¿Cómo tomo estos datos byte primas y convertirlo en algo así como PEM o algún otro formato que comprende una biblioteca criptográfica? ¿Debería basar64 para codificarlo? ¿Hay otras cosas que necesito hacer también?

Si sirve de ayuda, estoy tratando de usar la clave pública con la biblioteca M2Crypto disponible para Python.

+0

No, no es BASE64. Es una estructura ASN.1 que contiene un 'SEQUENCE' con dos elementos' INTEGER'. Mientras que el segundo elemento parece ser siempre '65537', el otro elemento parece tener el tamaño de clave. Pero todavía no tengo idea de cómo sacar exponente y módulo de ellos para exportarlo a otro formato. – miho

Respuesta

2

Creo que tendrá que buscar en http://www.openssl.org/docs/crypto/pem.html# quizá:

int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, 
            unsigned char *kstr, int klen, 
            pem_password_cb *cb, void *u); 
+1

Eso significaría incluir OpenSSL en mi proyecto. He estado haciendo todo con la biblioteca integrada 'CommonCrypto'. Dice en esos documentos vinculados que PEM es básicamente base64 que codifica la clave, y luego la envuelve con líneas de encabezado. Intenté esto, pero no pude hacer que funcione con 'M2Crypto'. ¿Los bytes producidos por la función 'getPublicKeyBits' están arriba en el" formato "correcto, de modo que solo puedo basar64 para codificarlos? Me disculpo, no sé mucho sobre criptografía y estos estándares y bibliotecas. –

+0

es una base64 de la versión DER de la clave ... http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf –

+0

Ah, así que parece ' getPublicKeyBits' devuelve los bits 'DER' codificados de acuerdo con [this] (http://stackoverflow.com/questions/3840005/how-to-find-out-the-modulus-and-exponent-of-rsa-public-key -on-iphone-objetivo-c). Entonces si base64 lo codifica y envuelve la cadena con las líneas de encabezado, debería funcionar. Intenté esto, pero quizás el código que solía codificar base64 era incorrecto. ¡Gracias por la ayuda! Marcaré esta respuesta como correcta, ya que fue muy útil. –

1

Esta página tiene algunos grandes consejos y código de ejemplo para el envasado de los datos que tiene en el formato PEM para que pueda enviarlo a un servidor :

http://blog.wingsofhermes.org/?p=42

no necesita toda la biblioteca OpenSSL compilado desde el código fuente y enlazado estáticamente para hacerlo. Estoy usando solo esta técnica, envolviendo la clave base 64 en "----- BEGIN PUBLIC KEY -----" y puede ser leída y utilizada por una aplicación Rails usando las clases ruby ​​openssl estándar.

Cuestiones relacionadas