2012-04-16 7 views
6

Używam biblioteki commoncrypto na telefonie iPhone do utworzenia pary kluczy RSA i próbuję wysłać klucz publiczny do serwera (Python), aby można było używać do weryfikacji podpisu wysłanego z telefonu.Nie mogę się dowiedzieć, jak opublikować klucz publiczny wygenerowany na telefonie iPhone

mi stosując dokładnie kod z przykładu CommonCrypto stosując metodę getPublicKeyBits() która wygląda następująco:

`- (NSData ) getPublicKeyBits { OSStatus sanityCheck = noerr; NSData publicKeyBits = nil; NSData * publicTag = [[przydział NSData] 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; 

} `

Problem polega na tym, że nie wiem, jak dokładnie, klucz jest przechowywany lub jak ją przejść. Używam modelu getPublicKeyBits(), aby uzyskać go w strukturze NSData. Zaimportowałem bibliotekę, aby ją zakodować w base64. Dostaję klucz (SHA1, chciałbym przenieść się do SHA256, ale to jest drugorzędne, aby to działało), a wersja base64 wygląda jak inne klucze, które znalazłem tutaj i u innych osób rozwiązujących problemy RSA.

Próbuję użyć biblioteki M2Crypto w Pythonie i kiedy próbuję sprawdzić, otrzymuję komunikat o błędzie "RSA Error: No Start Line". Oto kod używam do otrzymania klucza publicznego:

pubKey = request.form['publickey'] 

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

a kod używam do sprawdzenia podpis:

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) 

Jestem bardzo zakłopotany, co ja źle, ale czuję, że zbliżam się do siebie. Jeśli cała moja metoda nie jest taka, jak byś to zrobił, bardzo chciałbym usłyszeć inny sposób generowania kluczy RSA w telefonie, opublikować klucz publiczny na serwerze, a następnie zweryfikować podpis z telefonu na tym serwerze .

Dzięki!

+0

Czy mógłbyś opublikować swój kod iOS, którego używasz do tworzenia danych klucza publicznego? – MrTJ

+0

zaktualizowany post z kodem – brennen

Odpowiedz

1

Można użyć getPublicKeyBits metodę z SecKeyWrapper w kodzie Jabłko CryptoExercise

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

To pozwoli Ci DER zakodowane dane binarne. Następnie użyj poniższej metody, aby załadować ją do M2Crypto w Pythonie: (Zasadniczo, po prostu base64 it i wywołaj jedną metodę.)

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

Mam ARC włączona wersję tego getPublicKeyBits metody, ale nie dostał około wysłaniem go jeszcze.

Aktualizacja - na re-czytając swoje pytanie, odpowiedź jest rzeczywiście tutaj:

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

Można to wykorzystać, aby uzyskać moduł i wykładnik jako NSData, które powinny być w stanie łatwo przekonwertować na base64 lub swoją reprezentację wyboru.

0

Podstawową implementacją M2Crypto jest OpenSSL. OpenSSL nie importuje twojego czystego klucza publicznego podczas eksportowania go, ale tylko wtedy, gdy jest "osadzony" w prawdopodobnie samopodpisanym certyfikacie. Sprawdź, jak utworzyć certyfikat z podpisem własnym z Common Crypto lub Security framework, załóż klucz publiczny i podpisz go swoim kluczem prywatnym, wyodrębnij dane i wyślij je na serwer: powinno działać.

Zobacz także openssl_pkey_get_public not open public key, "no start line" error (druga odpowiedź)

+0

Co masz na myśli "wyodrębnić swoje dane"? – brennen

+0

To samo, co w przypadku klucza prywatnego: po uzyskaniu certyfikatu w pamięci skopiuj dane binarne do NSData i wyślij strumień bajtów na serwer. – MrTJ