我正在尝试实现RSA算法,我遵循了苹果reference
但是我在将uint8_t转换为NSData到NSString时遇到了问题。

到目前为止,我已经完成了这些操作。这些功能在reference中定义

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

}


为了加密我做了..

- (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转换为NSData转换为NSString或简单地转换为NSString以便我取回字符串。有关我的加密和密钥生成代码,请参考此reference

提前致谢..

最佳答案

我知道这个问题很老,被标记为已解决,但我来这里时遇到了类似的问题。
我发现的是,该行中的Apple docs的加密方法似乎存在错误

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


datalength在这里是错误的变量。我用cipherbuffersize替换为

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


现在一切对我来说都很好。我希望它对我以外的人有用。

关于iphone - 在RSA解密中将uint8_t转换为NSString,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14324813/

10-13 03:50