Converter NSData em String?

122

Estou armazenando uma chave privada openssl EVP_PKEY como nsdata. Para isso, estou serializando em um fluxo de bytes usando o código abaixo

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

onde pkey é do tipo EVP_PKEY. Então, estou armazenando os bytes do buffer 'p' como um NSData usando a linha fornecida abaixo

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

Agora estou convertendo-o para um NSString usando o código fornecido abaixo, mas quando imprimo no console está dando alguns outros caracteres.

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

Alguém poderia ajudar?

Basicamente, eu quero armazenar o EVP_PKEY em um banco de dados sqlite

Estou no caminho certo? Obrigado.

Zach
fonte
Como assim, "alguns outros personagens"? Está imprimindo caracteres extras no final que não deveriam estar lá ou apenas imprimindo caracteres completamente diferentes do que você espera?
Tom Harrington
Seu completamente diferente do que é ser
Zach
Tem certeza de que os dados são realmente codificados em UTF-8? Não estou familiarizado com o i2d_PrivateKey, mas seus resultados sugerem que você não está usando a codificação de string correta.
Tom Harrington
@TOm: Obrigado. era ASCIIEncoding. Agora está funcionando bem
Zach
Não, você não está no caminho certo aqui e todas as respostas parecem incorretas. Você deve usar codificação Base64 se você deseja converter os dados em NSDataa NSString.
Maarten Bodewes

Respostas:

260

Objetivo-C

Você pode usar (consulte a Referência de classe NSString )

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

Exemplo:

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

Observação : observe que o NSDatavalor deve ser válido para a codificação especificada (UTF-8 no exemplo acima), caso contrário, nilserá retornado:

Retorna nulo se a inicialização falhar por algum motivo (por exemplo, se os dados não representam dados válidos para codificação).

Prior Swift 3.0

String(data: yourData, encoding: NSUTF8StringEncoding)

Swift 3.0 em diante

String(data: yourData, encoding: .utf8)

Consulte String # init (data: encoding :) Referência

louiscoquio
fonte
Obrigado pela sua resposta. Eu já tentei isso sem sucesso.
Zach
26
No depurador:po [[NSString alloc] initWithData:myData encoding:4]
Berik
7
Como essa resposta pode ter vários upvotes, mesmo que eles NSDatapossam conter algum valor de byte, incluindo aqueles fora do intervalo UTF-8?
Maarten Bodewes
2
Porque as pessoas que estão aqui estão convertendo uma resposta de dados de um servidor em uma string.
Necro
1
e se o NSData <strong> de fato </strong> contiver valores fora do intervalo UTF-8?
Zennichimaro 06/02
24

Swift anterior 3.0:

String(data: yourData, encoding: NSUTF8StringEncoding)

Para o Swift 4.0:

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

Eu acredito que o seu "P" como o parâmetro dataWithBytes

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

deve ser "buf"

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

desde que i2d_PrivateKey coloca o ponteiro no buffer de saída p no final do buffer e aguarda por mais informações, e o buf ainda está apontando para o início do seu buffer.

O código a seguir funciona para mim, onde pkey é um ponteiro para um EVP_PKEY:

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);

Você pode usar um conversor on-line para converter seus dados binários na base 64 ( http://tomeko.net/online_tools/hex_to_base64.php?lang=en ) e compará-lo com a chave privada no seu arquivo cert depois de usar o seguinte comando e verificando a saída do mypkey.pem:

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

Mencionei sua pergunta e este site de funções do EVP para minha resposta.

aspergillusOryzae
fonte
2

Swift 3:

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

Uma maneira simples de converter NSData arbitrário em NSString é codificá-lo com base64.

NSString *base64EncodedKey = [keydata base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];

Você pode armazená-lo no seu banco de dados para reutilização posteriormente. Apenas decodifique de volta para NSData.

Billy
fonte
1

Swift 5 :

String(data: data!, encoding: String.Encoding.utf8)
Alexander Volkov
fonte
Esta é apenas uma cópia modificada da resposta pierre23 que é melhor para mim - eu normalmente usava esta página para copiar o código e precisava modificar seus dados para dados! isso leva tempo. Agora eu e você copiamos e colamos sem uma modificação.
Alexander Volkov
Esta não é uma pergunta relacionada ao Swift. Além disso, o exemplo de código na pergunta é código Objective-C. E não por último, o desembrulhamento forçado do seu código pode levar a falhas inesperadas.
Cristik
@Cristik A questão não está marcada como Obj-C.
Eiko
@AlexanderVolkov você pode adicionar um trecho de Xcode para isso, seria ainda mais rápido do que isso;)
Cristik