2013-01-14 34 views
0

我试图实现RSA算法,并且我跟着苹果reference。 但我遇到问题将uint8_t转换为NSData到NSString。将uint8_t转换为RSA解密中的NSString

我已经做了在reference

-(void)test{ 
    [self generateKeyPairPlease]; 
    NSData *data = [self encryptWithPublicKey]; //All goes well until here 
    [self decryptWithPrivateKey:data]; 

} 

定义加密我这样做使far..These功能..

- (NSData *)encryptWithPublicKey 
{ 
    OSStatus status = noErr; 

    size_t cipherBufferSize; 
    uint8_t *cipherBuffer;      // 1 

// [cipherBufferSize] 
    const uint8_t dataToEncrypt[] = "the quick brown fox jumps " 
          "over the lazy dog\0"; // 2 
    size_t dataLength = sizeof(dataToEncrypt)/sizeof(dataToEncrypt[0]); 

    SecKeyRef publicKey = NULL;         // 3 

    NSData * publicTag = [NSData dataWithBytes:publicKeyIdentifier 
      length:strlen((const char *)publicKeyIdentifier)]; // 4 

    NSMutableDictionary *queryPublicKey = 
          [[NSMutableDictionary alloc] init]; // 5 

    [queryPublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass]; 
    [queryPublicKey setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag]; 
    [queryPublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; 
    [queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef]; 
                   // 6 

    status = SecItemCopyMatching 
    ((__bridge CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKey); // 7 

// Allocate a buffer 

    cipherBufferSize = SecKeyGetBlockSize(publicKey); 
    cipherBuffer = malloc(cipherBufferSize); 

// Error handling 

    if (cipherBufferSize < sizeof(dataToEncrypt)) { 
     // Ordinarily, you would split the data up into blocks 
     // equal to cipherBufferSize, with the last block being 
     // shorter. For simplicity, this example assumes that 
     // the data is short enough to fit. 
     printf("Could not decrypt. Packet too large.\n"); 
     return NULL; 
    } 

    // Encrypt using the public. 
    status = SecKeyEncrypt( publicKey, 
           kSecPaddingPKCS1, 
           dataToEncrypt, 
           (size_t) dataLength, 
           cipherBuffer, 
           &cipherBufferSize 
           );        // 8 

// Error handling 
// Store or transmit the encrypted text 

    if (publicKey) CFRelease(publicKey); 

    NSData *encryptedData = [NSData dataWithBytes:cipherBuffer length:dataLength]; 

    free(cipherBuffer); 

    return encryptedData; 
} 

decryptWithPrivateKey我能不能转换uint8_t *plainBuffer(解密结果)到NSString。首先我试图把它转换成NSData打印时用NSLog它正确显示字节,但是NSData没有转换成字符串。

- (void)decryptWithPrivateKey: (NSData *)dataToDecrypt 
{ 
    OSStatus status = noErr; 

    size_t cipherBufferSize = [dataToDecrypt length]; 
    uint8_t *cipherBuffer = (uint8_t *)[dataToDecrypt bytes]; 

    size_t plainBufferSize; 
    uint8_t *plainBuffer; 

    SecKeyRef privateKey = NULL; 

    NSData * privateTag = [NSData dataWithBytes:privateKeyIdentifier 
             length:strlen((const char *)privateKeyIdentifier)]; 

    NSMutableDictionary *queryPrivateKey = [[NSMutableDictionary alloc] init]; 

    // Set the private key query dictionary. 
    [queryPrivateKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass]; 
    [queryPrivateKey setObject:privateTag forKey:(__bridge id)kSecAttrApplicationTag]; 
    [queryPrivateKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; 
    [queryPrivateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef]; 
    // 1 

    status = SecItemCopyMatching 
    ((__bridge CFDictionaryRef)queryPrivateKey, (CFTypeRef *)&privateKey); // 2 

    // Allocate the buffer 
    plainBufferSize = SecKeyGetBlockSize(privateKey); 
    plainBuffer = malloc(plainBufferSize); 

    if (plainBufferSize < cipherBufferSize) { 
     // Ordinarily, you would split the data up into blocks 
     // equal to plainBufferSize, with the last block being 
     // shorter. For simplicity, this example assumes that 
     // the data is short enough to fit. 
     printf("Could not decrypt. Packet too large.\n"); 
     return; 
    } 

    // Error handling 

    status = SecKeyDecrypt( privateKey, 
          kSecPaddingPKCS1, 
          cipherBuffer, 
          cipherBufferSize, 
          plainBuffer, 
          &plainBufferSize 
          );        // 3 

    //******************************************************************************* 
    // Not able to convert uint8_t *plainBuffer to string 
    // I also tried to convert it into NSData and then try to convert it into NSString but can't 
    //What Should i do here to get string back 


    if(privateKey) CFRelease(privateKey); 
} 
@end 

我想知道如何解密结果uint8_t plainBuffer转换为NSDataNSString或者干脆NSString,使我得到我的字符串back.For我的加密和密钥生成代码,请参阅本reference

在此先感谢..

+0

任何人都可以解释为什么这个问题投下来吗?它有什么不对 – codester

+0

我不知道谁低估了它。但我可以告诉你:你的问题没有足够的信息来弄清楚你的问题。我和其他用户都试图从你那里获得更多的信息,但你曾经给出的唯一答案是“我试过了,但它不起作用” - 没有解释你尝试了什么“它”,你是如何尝试的,它以什么方式失败等等。所以,就目前来看,你的问题是不可能调试的。但是如果你只是给我们提供了信息,那么潜在的问题将很容易调试。正如所写的,这意味着一个糟糕的问题。 – abarnert

+0

我非常抱歉。现在我没有转储,但我解决了我的问题。实际上这个例子是直接从苹果refrence和有一些问题。我跟着这个github [代码](https ://github.com/kuapay/iOS-Certificate--Key-and-Trust-Sample-Project)。再次感谢您的回复。 – codester

回答

0

我管理由以下这code。它的相同的代码来解决我的问题,但串的编码different.In encryptWithPublicKey功能我已经使用

uint8_t *dataToEncrypt= (uint8_t *)[@"the quick brown fox jumps over the lazy dog" UTF8String];

代替

const uint8_t dataToEncrypt[] = "the quick brown fox jumps " "over the lazy dog\0";

decryptWithPrivateKey我已经使用这个解码

NSData *decryptedData = [NSData dataWithBytes:plainBuffer length:plainBufferSize]; 
NSString *decryptedString = [[[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding] autorelease]; 
1

最有可能的问题是,你打电话+[stringWithCharacters:length:],其预计Unicode字符(更准确地说,UTF-16代码点),但你可能有UTF-8或其他8位编码。

您必须知道您的编码,因此您可以拨打+[stringWithCString:encoding:](或者,如果是UTF-8,则为+[stringWithUTF8String:])。

请注意,与stringWithCharacters不同,这些方法不占用长度,并且期望您的数据以空值终止。因此,除非您确定数据总是有终止符,否则您应该明确检查它,或者分配字符串,然后调用-[initWithBytes:length:encoding:]

如果您不知道在加密之前明文处于什么字符集,您需要了解。作为一个人,你通常可以通过查看它,特别是如果它主要是ASCII。用缓冲区创建一个NSData并记录下来并查看十六进制数。如果是UTF-16,则ASCII字符将与空值交替,因此'Hello'将为48 00 65 00 6C 00 6C 00 6F 00。但是电脑不会做出很好的猜测。 (原因+[stringWithContentsOfFile:usedEncoding:error:]通常会得到它的权利是,它看起来在扩展属性com.apple.TextEncoding,当他们保存一个文件,其中最Cocoa程序写。)

+0

感谢您的回应,我已经使用了很多技巧来将'plainBuffer'转换为NSString,但无法进行。您可以在** encryptWithPublicKey方法** [参考] http://developer.apple.com/中查看加密代码library/ios /#documentation/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html#// apple_ref/doc/uid/TP40001358-CH208-SW13。如果您能提供一些提示,它将会非常棒。 – codester

+0

@SahilWasan:你尝试了我上面的建议吗?密文从哪里来?加密前的明文是什么字符集? – abarnert

+0

是的,我尝试过,但得到空 – codester

6

我知道这个问题是旧的,标记为解决,但我有一个类似的问题来到这里。 我发现了什么是有似乎是在加密方法的错误在该行

NSData *encryptedData = [NSData dataWithBytes:cipherBuffer length:dataLength]; 

数据长度是错误的变量这里的苹果文档。我用cipherbuffersize替换它为

NSData *encryptedData = [NSData dataWithBytes:cipherBuffer length:cipherBufferSize]; 

和所有东西现在对我来说很好。我希望它对于别人比我有用。

+1

你刚刚帮了我很多。非常感谢! – arik

+0

Thanx的答案:) – souvickcse