AES Encryption pour un NSSsortingng sur l’iPhone

Quelqu’un peut-il me diriger dans la bonne direction pour pouvoir chiffrer une chaîne, en renvoyant une autre chaîne avec les données chiffrées? (J’ai essayé avec le cryptage AES256.) Je veux écrire une méthode qui prend deux instances NSSsortingng, l’une étant le message à crypter et l’autre étant un «mot de passe» pour le chiffrer avec – je suppose que je devrais générer la clé de cryptage avec le mot de passe, d’une manière qui peut être inversée si le code d’access est fourni avec les données cryptées. La méthode devrait alors renvoyer une NSSsortingng créée à partir des données chiffrées.

J’ai essayé la technique détaillée dans le premier commentaire de cet article , mais je n’ai pas eu de chance jusqu’à présent. CryptoExercise d’Apple a certainement quelque chose, mais je ne peux pas le comprendre … J’ai vu beaucoup de références à CCCrypt , mais il a échoué dans tous les cas où je l’ai utilisé.

Je devrais aussi pouvoir déchiffrer une chaîne chiffrée, mais j’espère que c’est aussi simple que kCCEncrypt / kCCDecrypt.

Comme vous n’avez posté aucun code, il est difficile de savoir exactement quels problèmes vous rencontrez. Cependant, le post de blog auquel vous accédez semble fonctionner assez bien … à part les virgules supplémentaires dans chaque appel à CCCrypt() qui ont causé des erreurs de compilation.

Un commentaire ultérieur sur cet article inclut ce code adapté , qui fonctionne pour moi, et semble un peu plus simple. Si vous incluez leur code pour la catégorie NSData, vous pouvez écrire quelque chose comme ceci: (Remarque: Les appels à printf() servent uniquement à démontrer l’état des données à différents points – dans une application réelle, imprimer ces valeurs.)

 int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSSsortingng *key = @"my password"; NSSsortingng *secret = @"text to encrypt"; NSData *plain = [secret dataUsingEncoding:NSUTF8SsortingngEncoding]; NSData *cipher = [plain AES256EncryptWithKey:key]; printf("%s\n", [[cipher description] UTF8Ssortingng]); plain = [cipher AES256DecryptWithKey:key]; printf("%s\n", [[plain description] UTF8Ssortingng]); printf("%s\n", [[[NSSsortingng alloc] initWithData:plain encoding:NSUTF8SsortingngEncoding] UTF8Ssortingng]); [pool drain]; return 0; } 

Étant donné ce code et le fait que les données chiffrées ne se traduisent pas toujours bien dans une NSSsortingng, il peut être plus pratique d’écrire deux méthodes qui englobent les fonctionnalités dont vous avez besoin, en avant et en arrière …

 - (NSData*) encryptSsortingng:(NSSsortingng*)plaintext withKey:(NSSsortingng*)key { return [[plaintext dataUsingEncoding:NSUTF8SsortingngEncoding] AES256EncryptWithKey:key]; } - (NSSsortingng*) decryptData:(NSData*)ciphertext withKey:(NSSsortingng*)key { return [[[NSSsortingng alloc] initWithData:[ciphertext AES256DecryptWithKey:key] encoding:NSUTF8SsortingngEncoding] autorelease]; } 

Cela fonctionne définitivement sur Snow Leopard, et @Boz rapporte que CommonCrypto fait partie du Core OS de l’iPhone. Les /usr/include/CommonCrypto 10.4 et 10.5 ont toutes les deux /usr/include/CommonCrypto , bien que 10.5 ait une page de CCCryptor.3cc pour CCCryptor.3cc et 10.4 non, alors YMMV.


EDIT: consultez cette question complémentaire sur l’utilisation du codage Base64 pour représenter les octets de données chiffrés sous forme de chaîne (si vous le souhaitez) en utilisant des conversions sûres et sans perte.

J’ai rassemblé une collection de catégories pour NSData et NSSsortingng, qui utilisent des solutions trouvées sur le blog de Jeff LaMarche et quelques conseils de Quinn Taylor sur Stack Overflow.

Il utilise des catégories pour étendre NSData pour fournir le chiffrement AES256 et offre également une extension de NSSsortingng à BASE64 pour encoder des données chiffrées en toute sécurité dans des chaînes.

Voici un exemple pour montrer l’utilisation du chiffrement des chaînes:

 NSSsortingng *plainSsortingng = @"This ssortingng will be encrypted"; NSSsortingng *key = @"YourEncryptionKey"; // should be provided by a user NSLog( @"Original Ssortingng: %@", plainSsortingng ); NSSsortingng *encryptedSsortingng = [plainSsortingng AES256EncryptWithKey:key]; NSLog( @"Encrypted Ssortingng: %@", encryptedSsortingng ); NSLog( @"Decrypted Ssortingng: %@", [encryptedSsortingng AES256DecryptWithKey:key] ); 

Obtenez le code source complet ici:

https://gist.github.com/838614

Merci pour tous les conseils utiles!

— Michael

@owlstead, en ce qui concerne votre demande d’une “variante cryptographiquement sécurisée de l’une des réponses données”, veuillez consulter RNCryptor . Il a été conçu pour faire exactement ce que vous demandez (et a été construit en réponse aux problèmes avec le code répertorié ici).

RNCryptor utilise PBKDF2 avec salt, fournit un IV aléatoire et connecte HMAC (également généré à partir de PBKDF2 avec son propre sel). Il prend en charge le fonctionnement synchrone et asynchrone.

J’ai attendu un peu @QuinnTaylor pour mettre à jour sa réponse, mais comme il ne l’a pas fait, voici la réponse un peu plus claire et d’une manière qui se chargera sur XCode7 (et peut-être même plus). Je l’ai utilisé dans une application Cocoa, mais cela fonctionnera probablement aussi avec une application iOS. N’a pas d’erreurs ARC.

Collez avant toute section @implementation dans votre fichier AppDelegate.m ou AppDelegate.mm.

 #import  @implementation NSData (AES256) - (NSData *)AES256EncryptWithKey:(NSSsortingng *)key { // 'key' should be 32 bytes for AES256, will be null-padded otherwise char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) // fetch key data [key getCSsortingng:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8SsortingngEncoding]; NSUInteger dataLength = [self length]; //See the doc: For block ciphers, the output size will always be less than or //equal to the input size plus the size of one block. //That's why we need to add the size of one block here size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCKeySizeAES256, NULL /* initialization vector (optional) */, [self bytes], dataLength, /* input */ buffer, bufferSize, /* output */ &numBytesEncrypted); if (cryptStatus == kCCSuccess) { //the returned NSData takes ownership of the buffer and will free it on deallocation return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; } free(buffer); //free the buffer; return nil; } - (NSData *)AES256DecryptWithKey:(NSSsortingng *)key { // 'key' should be 32 bytes for AES256, will be null-padded otherwise char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) // fetch key data [key getCSsortingng:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8SsortingngEncoding]; NSUInteger dataLength = [self length]; //See the doc: For block ciphers, the output size will always be less than or //equal to the input size plus the size of one block. //That's why we need to add the size of one block here size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesDecrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCKeySizeAES256, NULL /* initialization vector (optional) */, [self bytes], dataLength, /* input */ buffer, bufferSize, /* output */ &numBytesDecrypted); if (cryptStatus == kCCSuccess) { //the returned NSData takes ownership of the buffer and will free it on deallocation return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; } free(buffer); //free the buffer; return nil; } @end 

Collez ces deux fonctions dans la classe @implementation souhaitée. Dans mon cas, j’ai choisi @implementation AppDelegate dans mon fichier AppDelegate.mm ou AppDelegate.m.

 - (NSSsortingng *) encryptSsortingng:(NSSsortingng*)plaintext withKey:(NSSsortingng*)key { NSData *data = [[plaintext dataUsingEncoding:NSUTF8SsortingngEncoding] AES256EncryptWithKey:key]; return [data base64EncodedSsortingngWithOptions:kNilOptions]; } - (NSSsortingng *) decryptSsortingng:(NSSsortingng *)ciphertext withKey:(NSSsortingng*)key { NSData *data = [[NSData alloc] initWithBase64EncodedSsortingng:ciphertext options:kNilOptions]; return [[NSSsortingng alloc] initWithData:[data AES256DecryptWithKey:key] encoding:NSUTF8SsortingngEncoding]; }