NSData in String konvertieren?

122

Ich speichere einen openssl privaten Schlüssel EVP_PKEY als nsdata. Dafür serialisiere ich mit dem folgenden Code in einen Byte-Stream

unsigned char *buf, *p;
int len;
len = i2d_PrivateKey(pkey, NULL);
buf = OPENSSL_malloc(len); 
p = buf;
i2d_PrivateKey(pkey, &p);

Dabei ist pkey vom Typ EVP_PKEY. Dann speichere ich die Bytes aus dem Puffer 'p' als NSData unter Verwendung der unten angegebenen Zeile

NSData *keydata = [NSData dataWithBytes:P length:len];

Jetzt konvertiere ich es mit dem unten angegebenen Code in einen NSString, aber wenn ich es in die Konsole drucke, gibt es einige andere Zeichen.

NSString *content =[ NSString stringWithCString:[keydata bytes] encoding:NSUTF8StringEncoding];

Könnte jemand helfen?

Grundsätzlich möchte ich EVP_PKEY in einer SQLite-Datenbank speichern

bin ich auf dem richtigen Weg? Vielen Dank.

Zach
quelle
Was meinst du mit "einigen anderen Charakteren"? Druckt es am Ende zusätzliche Zeichen, die nicht vorhanden sein sollten, oder druckt es nur ganz andere Zeichen als erwartet?
Tom Harrington
Es ist völlig anders als das, was es sein soll
Zach
Sind Sie sicher, dass die Daten tatsächlich UTF-8-codiert sind? Ich bin mit i2d_PrivateKey nicht vertraut, aber Ihre Ergebnisse deuten darauf hin, dass Sie nicht die richtige Zeichenfolgencodierung verwenden.
Tom Harrington
@TOm: Danke. es war ASCIIEncoding. Jetzt funktioniert es gut
Zach
Nein, Sie sind hier nicht auf dem richtigen Weg und alle Antworten scheinen falsch zu sein. Sie sollten Codierung verwenden base64 wenn Sie die Daten in konvertieren möchten NSDatazu NSString.
Maarten Bodewes

Antworten:

260

Ziel c

Sie können verwenden (siehe NSString-Klassenreferenz )

- (id)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding

Beispiel:

NSString *myString = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];

Anmerkung : Bitte beachten Sie, dass der NSDataWert für die angegebene Codierung gültig sein muss (UTF-8 im obigen Beispiel), andernfalls nilwird Folgendes zurückgegeben:

Gibt null zurück, wenn die Initialisierung aus irgendeinem Grund fehlschlägt (z. B. wenn Daten keine gültigen Daten für die Codierung darstellen).

Prior Swift 3.0

String(data: yourData, encoding: NSUTF8StringEncoding)

Swift 3.0 ab

String(data: yourData, encoding: .utf8)

Siehe String # init (Daten: Codierung :) Referenz

louiscoquio
quelle
Vielen Dank für Ihre Antwort. Ich habe das bereits ohne Erfolg versucht.
Zach
26
Auf dem Debugger:po [[NSString alloc] initWithData:myData encoding:4]
Berik
7
Wie kann diese Antwort zahlreiche positive Stimmen haben, auch wenn NSDatasie einen beliebigen Bytewert enthalten kann, einschließlich solcher außerhalb des UTF-8-Bereichs?
Maarten Bodewes
2
Weil die Leute, die hier sind, eine Datenantwort von einem Server in eine Zeichenfolge konvertieren.
Necro
1
Was ist, wenn NSData <strong> tatsächlich </ strong> Werte außerhalb des UTF-8-Bereichs enthält?
Zennichimaro
24

Prior Swift 3.0:

String(data: yourData, encoding: NSUTF8StringEncoding)

Für Swift 4.0:

String(data: yourData, encoding: .utf8)
pierre23
quelle
3

Ich glaube, Ihr "P" als dataWithBytes-Parameter

NSData *keydata = [NSData dataWithBytes:P length:len];

sollte "buf" sein

NSData *keydata = [NSData dataWithBytes:buf length:len];

da i2d_PrivateKey den Zeiger auf den Ausgabepuffer p am Ende des Puffers setzt und auf weitere Eingaben wartet und buf immer noch auf den Anfang Ihres Puffers zeigt.

Der folgende Code funktioniert für mich, wenn pkey ein Zeiger auf einen EVP_PKEY ist:

unsigned char *buf, *pp;
int len = i2d_PrivateKey(pkey, NULL);
buf = OPENSSL_malloc(len); 
pp = buf;
i2d_PrivateKey(pkey, &pp);

NSData* pkeyData = [NSData dataWithBytes:(const void *)buf length:len];
DLog(@"Private key in hex (%d): %@", len, pkeyData);

Sie können einen Online-Konverter verwenden, um Ihre Binärdaten in Base 64 ( http://tomeko.net/online_tools/hex_to_base64.php?lang=de ) zu konvertieren und mit dem privaten Schlüssel in Ihrer Zertifikatdatei zu vergleichen, nachdem Sie den folgenden Befehl und verwendet haben Überprüfen der Ausgabe von mypkey.pem:

openssl pkcs12 -in myCert.p12 -nocerts -nodes -out mypkey.pem

Ich habe Ihre Frage und diese EVP-Funktionsseite für meine Antwort referenziert .

aspergillusOryzae
quelle
2

Swift 3:

String(data: data, encoding: .utf8)
Travis M.
quelle
1

Eine einfache Möglichkeit, beliebige NSData in NSString zu konvertieren, besteht darin, sie mit base64 zu codieren.

NSString *base64EncodedKey = [keydata base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];

Sie können es dann zur späteren Wiederverwendung in Ihrer Datenbank speichern. Dekodieren Sie es einfach zurück in NSData.

Billy
quelle
1

Swift 5 :

String(data: data!, encoding: String.Encoding.utf8)
Alexander Volkov
quelle
Dies ist nur eine modifizierte Kopie der pierre23-Antwort, die für mich besser ist. Normalerweise habe ich diese Seite zum Kopieren des Codes verwendet und musste Ihre Daten in Daten ändern! das braucht Zeit. Jetzt kopieren und fügen Sie und ich ohne Änderung ein.
Alexander Volkov
Dies ist keine Swift-bezogene Frage. Das Codebeispiel in der Frage ist außerdem Objective-C-Code. Und nicht zuletzt kann das erzwungene Entpacken aus Ihrem Code zu unerwarteten Abstürzen führen.
Cristik
@Cristik Die Frage ist nicht als Obj-C markiert.
Eiko
@AlexanderVolkov Sie können ein Xcode-Snippet dafür hinzufügen, es wäre sogar noch schneller als dies;)
Cristik