2017-03-15 2 views
-3

Ich versuche NSString mit dieser Klasse für dieObjective-c AES128 verschlüsseln

#import "NSData+AES.h" 
#import <CommonCrypto/CommonCryptor.h> 

@implementation NSData (AES) 

- (NSData *)AES128EncryptedDataWithKey:(NSString *)key 
{ 
    return [self AES128EncryptedDataWithKey:key iv:nil]; 
} 

- (NSData *)AES128DecryptedDataWithKey:(NSString *)key 
{ 
    return [self AES128DecryptedDataWithKey:key iv:nil]; 
} 

- (NSData *)AES128EncryptedDataWithKey:(NSString *)key iv:(NSString *)iv 
{ 
    return [self AES128Operation:kCCEncrypt key:key iv:iv]; 
} 

- (NSData *)AES128DecryptedDataWithKey:(NSString *)key iv:(NSString *)iv 
{ 
    return [self AES128Operation:kCCDecrypt key:key iv:iv]; 
} 

- (NSData *)AES128Operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv 
{ 
    char keyPtr[kCCKeySizeAES128 + 1]; 
    bzero(keyPtr, sizeof(keyPtr)); 
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 

    char ivPtr[kCCBlockSizeAES128 + 1]; 
    bzero(ivPtr, sizeof(ivPtr)); 
    if (iv) { 
     [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding]; 
    } 

    NSUInteger dataLength = [self length]; 
    size_t bufferSize = dataLength + kCCBlockSizeAES128; 
    void *buffer = malloc(bufferSize); 

    size_t numBytesEncrypted = 0; 
    CCCryptorStatus cryptStatus = CCCrypt(operation, 
              kCCAlgorithmAES128, 
              kCCOptionPKCS7Padding | kCCOptionECBMode, 
              keyPtr, 
              kCCBlockSizeAES128, 
              ivPtr, 
              [self bytes], 
              dataLength, 
              buffer, 
              bufferSize, 
              &numBytesEncrypted); 
    if (cryptStatus == kCCSuccess) { 
     return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; 
    } 
    free(buffer); 
    return nil; 
} 

@end 

Ich benutze diesen Code zu verschlüsseln:

//This is MD5 key 
NSString *key = @"7046dd94480f28dbf4b2e3cb6fa3864a"; 

NSData *plainDataEmail = [@"[email protected]" dataUsingEncoding:NSUTF8StringEncoding]; 
NSData *encryptedDataEmail = [plainDataEmail AES128EncryptedDataWithKey:key]; 
NSString *encryptedStringEmail = [encryptedDataEmail base64EncodedStringWithOptions:0]; 

encryptedStringEmail ist:

JXf7l5dH3qaYvudxCzE98w== 

Jetzt I‘ m Überprüfung der gleichen Details auf this site, und der Grund ist:

gnZZGbRaVtCG8Z8Xf732Cw== 

Bitte sagen Sie mir, was das Problem in meinem Objective-C-Code ist

+0

Mein Fehler, ich habe die Links bearbeitet –

+0

Erzeugt der Code die gleiche JXf7l5dH3qaYvudxCzE98w == immer in diesem Fall? –

+0

Ja dasselbe Ergebnis –

Antwort

0

Ihre Links sind nicht richtig funktionieren.

Ich bin in der Vergangenheit auf ein ähnliches Problem gestoßen. Ich vermute, dass die AES128EncryptedDataWithKey-Methode Ihren Schlüssel, der eine NSString ist, in Binärcode umwandelt, der eine andere Methode oder eine andere Codierung als die Site verwendet, die Sie verknüpfen wollten.

+0

Sorry, mein Fehler, ich habe die Frage noch einmal bearbeitet –

2

Hier gibt es viele Dinge. Fast jeder Schritt scheint zu einem gewissen Grad falsch zu sein. Ich kann durch die gehen, aber dieses ganze Schema ist sehr unsicher. Meine Empfehlung ist, wenn Sie nicht spezifisch mit aesencryption.net übereinstimmen müssen, ein plattformübergreifendes, sicheres Format wie RNCryptor.

Kurze Version: Es gibt keine allgemein akzeptierte Möglichkeit, AES zu verwenden. Sie müssen genau wissen, wie beide Seiten ihre Formate implementiert und angepasst haben. aesencryption.net erklärt ihren Ansatz nicht (die Codebeispiele scheinen nicht miteinander oder mit dem Website-Tool übereinzustimmen). Es ist sehr schwierig, AES korrekt zu verwenden, so dass fast jeder willkürlich gewählte Ansatz sehr unsicher ist.

Sie haben eine Schlüsselannahme, die falsch ist: dass mit demselben Schlüssel verschlüsselter Klartext immer den gleichen Chiffretext generieren sollte. In einem sicheren Schema sollte dies nie wahr sein. (Wenn Sie die Tools verwenden, die Sie korrekt verwenden, erhalten Sie eine übereinstimmende Ausgabe, aber das liegt daran, dass es sich um unsichere Implementierungen handelt.) Außer in seltenen Fällen, in denen Sie Reproduzierbarkeit benötigen und absichtlich die Sicherheit dafür opfern, sollte es mindestens ein zufälliges Element im Schema, das bewirkt, dass jede Verschlüsselung eindeutig ist. Im obigen Code sollte dieses zufällige Element die IV sein. Sie sollten eine zufällige IV generieren und an den Verschlüssler übergeben.

Während Sie eine 128-Bit-Verschlüsselung erwarten, ist Ihr Schlüssel tatsächlich 256 Bit lang. Sie denken wahrscheinlich, dass das erste Byte Ihres Schlüssels 0x70 ist, aber das ist nicht korrekt. Es ist 0x37, das ist die UTF-8-Codierung von "7". Sie übergeben eine Zeichenfolge, und es ist nur UTF-8-codiert und dann abgeschnitten (oder Null gefüllt), um 16 Bytes zu sein. (Dies ist einer der Hauptgründe, warum dieser ObjC-Code so unsicher ist.)

Es ist unklar, was aesencryption.net mit dem Schlüssel macht; Sie zeigen ihren Code nicht und ihre Codebeispiele sind nicht klar. Ihr Java-Beispiel hashe den Schlüssel, aber ich denke nicht, dass ihr PHP-Code tut. Die Art, wie sich die Seite verhält, ich glaube nicht, dass sie Hashes hat, aber ihr Verhalten ist irgendwie komisch. Schlüssel, die 33 Zeichen lang sind, verschlüsseln genau die gleichen wie 32 Zeichen, so dass sie deutlich abgeschnitten werden. Aber es schneidet auf 32 Bytes ab, nicht auf 16 Bytes, selbst für 128-bit Schlüssel. Das ist alles sehr komisch.

Schließlich verwendet der ObjC-Code den ECB-Modus, der so ziemlich der schlechteste Modus ist, den Sie für die allgemeine Verschlüsselung wählen können. Es gibt einige sehr spezifische Fälle, wo es nützlich ist, aber das ist nicht einer von ihnen.Es ist nicht offensichtlich, was aesencryption.net verwendet, obwohl ihre Codebeispiele ECB verwenden.