Algorithme MD5 en Objective-C

Réponses:

219

md5 est disponible sur l'iPhone et peut être ajouté en complément pour ie NSStringetNSData autres ci-dessous.

MyAdditions.h

@interface NSString (MyAdditions)
- (NSString *)md5;
@end

@interface NSData (MyAdditions)
- (NSString*)md5;
@end

MyAdditions.m

#import "MyAdditions.h"
#import <CommonCrypto/CommonDigest.h> // Need to import for CC_MD5 access

@implementation NSString (MyAdditions)
- (NSString *)md5
{
    const char *cStr = [self UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5( cStr, (int)strlen(cStr), result ); // This is the md5 call
    return [NSString stringWithFormat:
        @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
        result[0], result[1], result[2], result[3], 
        result[4], result[5], result[6], result[7],
        result[8], result[9], result[10], result[11],
        result[12], result[13], result[14], result[15]
        ];  
}
@end

@implementation NSData (MyAdditions)
- (NSString*)md5
{
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5( self.bytes, (int)self.length, result ); // This is the md5 call
    return [NSString stringWithFormat:
        @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
        result[0], result[1], result[2], result[3], 
        result[4], result[5], result[6], result[7],
        result[8], result[9], result[10], result[11],
        result[12], result[13], result[14], result[15]
        ];  
}
@end

ÉDITER

Ajout de NSData md5 car j'en avais besoin moi-même et je pensais que c'était un bon endroit pour enregistrer ce petit extrait ...

Ces méthodes sont vérifiées à l'aide des vecteurs de test NIST MD5 dans http://www.nsrl.nist.gov/testdata/

Epatel
la source
Cela tire-t-il l'intégralité du fichier en mémoire?
openfrog
Il ne s’agit pas de fichiers. Si vous souhaitez créer un MD5 à partir d'un fichier avec ces méthodes, vous pouvez faire NSData * fileContents = [NSData dataWithContentsOfFile: @ "<yourPath>"]; NSString * myHash = [fileContents md5]; Et oui, cela tirerait tout le fichier en mémoire. Si vous trouvez une solution qui fonctionne avec les flux de fichiers, veuillez la publier comme réponse.
Klaas
1
Si vous avez besoin d'un fichier de hachage, vous devez utiliser CC_MD5_Init, puis CC_MD5_Update pour toutes les données de fichier, et après cela - CC_MD5_Finish.
Nickolay Olshevsky
7
Compilation pour une architecture 64 bits, l'appel à strlenrenvoie l'avertissement: "La conversion implicite perd la précision entière: 'unsigned long' en 'CC_LONG' (alias 'unsigned int')"
MaxGabriel
55

Vous pouvez utiliser la bibliothèque Common Crypto intégrée pour ce faire. N'oubliez pas d'importer:

#import <CommonCrypto/CommonDigest.h>

puis:

- (NSString *) md5:(NSString *) input
{
    const char *cStr = [input UTF8String];
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
    CC_MD5( cStr, strlen(cStr), digest ); // This is the md5 call

    NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];

    for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
    [output appendFormat:@"%02x", digest[i]];

    return  output;
}
Bruno Koga
la source
J'ai implémenté le code ci-dessus mais lors de l'exécution de l'application, il plante (CC_MD5 (cStr, strlen (cStr), digest) ----> cette ligne lance une exception disant EXC_BAD_ACCESS)
Nilesh Kumar
@wimcNilesh vérifie selfavant l'exécution; si le moi est nul, il va s'écraser.
brandonscript
4
Cette réponse est beaucoup plus claire à lire que les autres; une chose dont il a besoin est un casting (int)avant, strlenpar exemple (int)strlen...
brandonscript
Hay C'est gentil +1 vote positif, et pouvez-vous s'il vous plaît également fournir une méthode de décryptage md5 identique à votre cryptage.
Ayaz
@Ayaz MD5 ne peut pas être déchiffré (au moins simplement avec une méthode).
albanx
9

Si les performances sont importantes, vous pouvez utiliser cette version optimisée. C'est environ 5 fois plus rapide que ceux avec stringWithFormatouNSMutableString .

Il s'agit d'une catégorie de NSString.

- (NSString *)md5
{
    const char* cStr = [self UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cStr, strlen(cStr), result);

    static const char HexEncodeChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    char *resultData = malloc(CC_MD5_DIGEST_LENGTH * 2 + 1);

    for (uint index = 0; index < CC_MD5_DIGEST_LENGTH; index++) {
        resultData[index * 2] = HexEncodeChars[(result[index] >> 4)];
        resultData[index * 2 + 1] = HexEncodeChars[(result[index] % 0x10)];
    }
    resultData[CC_MD5_DIGEST_LENGTH * 2] = 0;

    NSString *resultString = [NSString stringWithCString:resultData encoding:NSASCIIStringEncoding];
    free(resultData);

    return resultString;
}
Pavel Alexeev
la source
0

Eh bien, puisque les gens ont demandé une version de flux de fichiers. J'ai modifié un joli petit extrait fait par Joel Lopes Da Silva qui fonctionne avec MD5, SHA1 et SHA512 ET il utilise des flux. Il est conçu pour iOS mais fonctionne avec des modifications minimes sur OSX (supprimez la méthode ALAssetRepresentation). Il peut effectuer des sommes de contrôle pour les fichiers ayant un chemin de fichier ou ALAssets (en utilisant ALAssetRepresentation). Il segmente les données en petits paquets, ce qui réduit au minimum l'impact sur la mémoire, quelle que soit la taille du fichier / de l'actif.

Il est actuellement situé sur github ici: https://github.com/leetal/FileHash

Alexandre W
la source
Le code que Joel a publié a une condition de concurrence, et il semble que le vôtre en hérite. Voir le commentaire que j'ai publié sur le post de Joel. joel.lopes-da-silva.com/2010/09/07/…
xyzzycoder
Merci! Je l'ai corrigé maintenant. Cela n'a jamais été un problème pour moi puisque dans l'implémentation d'origine, je l'ai toujours exécuté dans un fil dédié;)
Alexander W
0

Toute raison de ne pas utiliser l'implémentation Apple: https://developer.apple.com/library/mac/documentation/Security/Conceptual/cryptoservices/GeneralPurposeCrypto/GeneralPurposeCrypto.html#//apple_ref/doc/uid/TP40011172-CH9-SW1

Recherchez le Guide des services cryptographiques sur le site des développeurs Apple.

vpathak
la source
Le lien couvre Common Crypto que la plupart des réponses ici utilisent.
zaph
1
Bien sûr, l'algo est le même. Mais notez que la mise en œuvre de votre propre algorithme cryptographique peut introduire des failles. Il faut beaucoup de durcissement pour que cela soit correct dans tous les scénarios. L'utilisation de la version bibliothèque est donc à privilégier, dans le cas courant.
vpathak