使用 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
.
之前成功生成的私钥和 public 密钥的引用
加密函数如下所示:
- (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]
return 128.
谁能帮我解决这个问题?
来自文档:
cipherTextLen - On entry, the size of the buffer provided in the
cipherText parameter. On return, the amount of data actually placed in
the buffer.
您没有为 ciphertextBufferLength
设置任何值。
更新#1
在 SecKeyGeneratePair()
中你的参数有误:public 密钥参数必须在第一个,私钥在第二个。我认为这就是您出现错误代码 -4 的原因。
更新#2
当您修复更新 #1 中的问题时,您将看到错误代码 -50 (errSecParam),因为您的密文长度错误。下面是正确的 encryption/decryption 的样子:
[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);
除了上面的正确答案,为我解决的还有以下知识:
如果您尝试使用引用 私钥. [=10] 的 SecKeyRef 加密任何内容,您将得到 -4 =]
想一想。使用 私钥 加密的任何内容都不安全,因为 public 密钥是 public。 /脸掌
所以,是的,Apple 的框架做了负责任的事情,只是阻止您使用私钥加密某些东西。因为如果它允许你做那么愚蠢的事情,那么它会给你一种虚假的安全感,这是不负责任的。
我正在尝试使用 iOS 上的安全框架使用 RSA 加密一些数据。我想加密一个简单的 base64 编码字符串,如下所示:
NSData *data = [[NSData alloc] initWithBase64EncodedString:@"aGFsbG8=" options:0x0];
NSData *encrypted = [pair encrypt:data];
pair
变量包含对使用 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]
return 128.
谁能帮我解决这个问题?
来自文档:
cipherTextLen - On entry, the size of the buffer provided in the cipherText parameter. On return, the amount of data actually placed in the buffer.
您没有为 ciphertextBufferLength
设置任何值。
更新#1
在 SecKeyGeneratePair()
中你的参数有误:public 密钥参数必须在第一个,私钥在第二个。我认为这就是您出现错误代码 -4 的原因。
更新#2
当您修复更新 #1 中的问题时,您将看到错误代码 -50 (errSecParam),因为您的密文长度错误。下面是正确的 encryption/decryption 的样子:
[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);
除了上面的正确答案,为我解决的还有以下知识:
如果您尝试使用引用 私钥. [=10] 的 SecKeyRef 加密任何内容,您将得到 -4 =]
想一想。使用 私钥 加密的任何内容都不安全,因为 public 密钥是 public。 /脸掌
所以,是的,Apple 的框架做了负责任的事情,只是阻止您使用私钥加密某些东西。因为如果它允许你做那么愚蠢的事情,那么它会给你一种虚假的安全感,这是不负责任的。