繁体   English   中英

使用SecKeyEncrypt进行RSA加密会产生错误-4(errSecUnimplemented)

[英]RSA encryption using SecKeyEncrypt gives error -4 (errSecUnimplemented)

我正在尝试使用iOS上的安全性框架使用RSA加密某些数据。 我想加密一个简单的base64编码的字符串,如下所示:

NSData *data = [[NSData alloc] initWithBase64EncodedString:@"aGFsbG8=" options:0x0];
NSData *encrypted = [pair encrypt:data];

pair变量保存对使用SecKeyGeneratePair之前成功生成的私钥和公钥的SecKeyGeneratePair

加密函数如下所示:

- (NSData *)encrypt:(NSData *)data {
    void *buffer = malloc([self blockSize] * sizeof(uint8_t));
    memset(buffer, 0x0, [self blockSize]);
    size_t ciphertextBufferLength = [data length];
    OSStatus res = SecKeyEncrypt([self keyRef], 0x1, [data bytes], [data length], &buffer[0], &ciphertextBufferLength);
    NSLog(@"Result of encryption: %d", res);
    return [NSData dataWithBytesNoCopy:buffer length:[self blockSize] freeWhenDone:YES];
}

[self blockSize]的实现非常简单:

- (unsigned long)blockSize {
    return SecKeyGetBlockSize(keyRef);
}

我使用以下功能生成密钥:

- (BOOL)generateNewKeyPairOfSize:(unsigned int)keySize
{
    SecKeyRef privKey = [[self publicKey] keyRef];
    SecKeyRef pubKey = [[self publicKey] keyRef];

    NSDictionary *privateKeyDict = @{ (__bridge id)kSecAttrIsPermanent : @(YES), (__bridge id)kSecAttrApplicationTag : [[self privateKey] tag] };
    NSDictionary *publicKeyDict = @{ (__bridge id)kSecAttrIsPermanent : @(YES), (__bridge id)kSecAttrApplicationTag : [[self publicKey] tag] };
    NSDictionary *keyDict = @{ (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeRSA, (__bridge id)kSecAttrKeySizeInBits : @(keySize), (__bridge id)kSecPublicKeyAttrs : publicKeyDict, (__bridge id)kSecPrivateKeyAttrs : privateKeyDict };
    OSStatus res = SecKeyGeneratePair((__bridge CFDictionaryRef)keyDict, &privKey, &pubKey);
    NSLog(@"Result of generating keys: %d", res);

    [[self publicKey] setKeyRef:pubKey];
    [[self privateKey] setKeyRef:privKey];

    return YES;
}

问题是res值为-4 ,根据文档表示errSecUnimplemented 我不确定我在做什么错,因为我需要所有参数。 我不确定参数和位置是否有错误。 调用[self blockSize]返回128。

谁能帮我这个?

从文档:

cipherTextLen-输入时,在cipherText参数中提供的缓冲区的大小。 返回时,实际放置在缓冲区中的数据量。

您没有为ciphertextBufferLength设置任何值。

更新#1

SecKeyGeneratePair()您有错误的参数:公钥参数必须是第一个,私钥是第二个。 我认为这就是您出现错误代码-4的原因。

更新#2

当您从更新#1修复问题时,您将看到错误代码-50(errSecParam),因为您的密文长度是错误的。 正确的加密/解密如下所示:

[self generateNewKeyPairOfSize:1024];

NSData *data = [[NSData alloc] initWithBase64EncodedString:@"aGFsbG8=" options:0x0];

size_t cipherTextSize = [self blockSize];
uint8_t *cipherText = malloc(cipherTextSize);
memset(cipherText, 0, cipherTextSize);
OSStatus res = SecKeyEncrypt(_publicKey, kSecPaddingPKCS1, [data bytes], data.length, cipherText, &cipherTextSize);
NSLog(@"Result of encryption: %d", res);

size_t plainTextSize = cipherTextSize;
uint8_t *plainText = malloc(plainTextSize);
res = SecKeyDecrypt(_privateKey, kSecPaddingPKCS1, cipherText, cipherTextSize, plainText, &plainTextSize);
NSLog(@"Result of decryption: %d", res);

除了上述正确答案外,为我解决的还有以下知识:

如果您尝试使用引用私钥的SecKeyRef加密任何内容,则将得到-4。

想一想。 私有密钥加密的任何东西都不是安全的,因为公共密钥是公共的 /捂脸

所以,是的,Apple的框架负责任地做事,并且只是阻止您使用私钥对某些事物进行加密。 因为如果它允许您做一些愚蠢的事情,那么它将给您一种错误的安全感,这是不负责任的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM