2012-04-16 10 views
6

Estoy usando la biblioteca commoncrypto en el iPhone para crear un par de claves RSA y estoy tratando de enviar la clave pública a un servidor (Python) para que pueda usar para verificar una firma enviada desde el teléfono.No se puede averiguar cómo publicar la clave pública generada en el iPhone

estoy usando el código exacto del ejemplo CommonCrypto utilizando el método getPublicKeyBits() que se parece a esto:

`- (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; 

} `

El problema es que no sé cómo, exactamente, se almacena la clave o la forma de pasarlo. Estoy usando el getPublicKeyBits() para obtenerlo en una estructura NSData, y he importado una biblioteca para codificarlo en base64. Obtengo una clave (SHA1, me gustaría pasar a SHA256, pero eso es secundario para que esto funcione) y la versión base64 se parece a otras claves que he encontrado aquí y a otras personas que resuelven problemas de RSA.

He estado tratando de usar la biblioteca M2Crypto en Python y cuando intento verificar que obtengo el error "RSA Error: No Start Line". Aquí está el código que estoy usando para recibir la clave pública:

pubKey = request.form['publickey'] 

uid = uuid4().hex 
while not unique(uid, User): 
    uid = uuid.uuid4().hex 
user = User(uid, email, secret, pubKey) 

Y el código que estoy usando para comprobar la firma:

def validate(sessionKey, sig, pem): 
    bio = BIO.MemoryBuffer(pem.encode('ascii')) 
    rsa = RSA.load_pub_key_bio(bio) 
    pubkey = EVP.PKey() 
    pubkey.assign_rsa(rsa) 

    pubkey.reset_context(md='sha1') 
    pubkey.verify_init() 
    pubkey.verify_update(sessionKey) 

    return pubkey.verify_final(sig) 

Estoy muy confundido en cuanto a lo que soy haciendo el mal, pero siento que me estoy acercando. Si mi método completo no es la forma en que lo haría, me gustaría escuchar cualquier otra forma de generar claves RSA en el teléfono, publicar la clave pública en un servidor y luego verificar una firma desde el teléfono en ese servidor. .

Gracias!

+0

¿Podría publicar también su código iOS que utiliza para crear los datos de clave pública? – MrTJ

+0

publicación actualizada con el código – brennen

Respuesta

1

Puede utilizar el getPublicKeyBits método de SecKeyWrapper en el código de Apple CryptoExercise

https://developer.apple.com/library/ios/#samplecode/CryptoExercise/Listings/Classes_SecKeyWrapper_h.html

Esto le dará la codificación DER datos binarios. A continuación, utilice el siguiente método para cargarlo en M2Crypto en Python: (Básicamente, solo base64 e invoque un método.)

https://stackoverflow.com/a/5765576/584616

tengo un ARC versión de este getPublicKeyBits método activado, pero no he tenido tiempo de publicar todavía.

actualización - en volver a leer su pregunta, la respuesta es en realidad aquí:

How to find out the modulus and exponent of RSA Public Key on iPhone/Objective C

Puede utilizar esto para conseguir el módulo y exponente como NSData, que debe ser capaz de facilidad Convierta en base64 o su representación de elección.

0

La implementación subyacente de M2Crypto es OpenSSL. OpenSSL no importará su clave pública pura como la exportó, pero solo si está "incrustada" en un certificado posiblemente autofirmado. Vea cómo crear un certificado autofirmado con Common Crypto o Framework de seguridad, incruste su clave pública y fírmela con su clave privada, extraiga sus datos y envíela a su servidor: debería funcionar.

Ver también openssl_pkey_get_public not open public key, "no start line" error (la segunda respuesta)

+0

¿Qué quiere decir "extraer sus datos"? – brennen

+0

Lo mismo que usaste para tu clave privada: una vez que tienes el certificado en la memoria, copia los datos binarios en NSData y envía la secuencia de bytes al servidor. – MrTJ

Cuestiones relacionadas