使用SecKeyEncrypt和Secure Enclave时出错

时间:2016-12-21 07:33:57

标签: ios security public-key-encryption private-key

我尝试使用kSecAttrTokenIDSecureEnclave来生成KeyPair使用函数。 但是当尝试使用函数

加密数据时
SecKeyEncrypt(publicKey,padding,(const uint8_t *)[symmetricKey bytes],keyBufferSize,cipherBuffer,&cipherBufferSize);

获取错误代码-50,显示参数错误。 谁能告诉我我缺少的东西?

这是我生成密钥对并尝试加密数据的函数

- (void)generateKeyPair{
  OSStatus sanityCheck = noErr;

NSData *privateTag = [[NSData alloc] initWithBytes:privateKeyIdentifier length:sizeof(privateKeyIdentifier)];
NSData *publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)];


// Container dictionaries.
NSMutableDictionary * privateKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary * publicKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary * keyPairAttr = [[NSMutableDictionary alloc] init];


CFErrorRef error = NULL;
// Should be the secret invalidated when passcode is removed? If not then use `kSecAttrAccessibleWhenUnlocked`.
SecAccessControlRef sacObject = SecAccessControlCreateWithFlags(
                                                                kCFAllocatorDefault,
                                                                kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
                                                                kSecAccessControlTouchIDAny | kSecAccessControlPrivateKeyUsage,
                                                                &error
                                                                );

if (error != errSecSuccess) {
    NSLog(@"Generate key error: %@\n", error);
}
[privateKeyAttr setObject:(__bridge id)sacObject forKey:(id)kSecAttrAccessControl];

[keyPairAttr setObject:[NSNumber numberWithUnsignedInteger:256] forKey:(id)kSecAttrKeySizeInBits];
[keyPairAttr setObject:(id)kSecAttrTokenIDSecureEnclave forKey:(id)kSecAttrTokenID];
[keyPairAttr setObject:(id)kSecAttrKeyTypeECSECPrimeRandom forKey:(id)kSecAttrKeyType];

// Set the private key dictionary.
[privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecAttrIsPermanent];
[privateKeyAttr setObject:privateTag forKey:(id)kSecAttrApplicationTag];
// See SecKey.h to set other flag values.

// Set the public key dictionary.
[publicKeyAttr setObject:[NSNumber numberWithBool:NO] forKey:(id)kSecAttrIsPermanent];
[publicKeyAttr setObject:publicTag forKey:(id)kSecAttrApplicationTag];
// See SecKey.h to set other flag values.

// Set attributes to top level dictionary.
[keyPairAttr setObject:privateKeyAttr forKey:(id)kSecPrivateKeyAttrs];
[keyPairAttr setObject:publicKeyAttr forKey:(id)kSecPublicKeyAttrs];

// SecKeyGeneratePair returns the SecKeyRefs just for educational purposes.
sanityCheck = SecKeyGeneratePair((CFDictionaryRef)keyPairAttr, &publicKeyRef, &privateKeyRef);
LOGGING_FACILITY( sanityCheck == noErr && publicKeyRef != NULL && privateKeyRef != NULL, @"Something really bad went wrong with generating the key pair." );


//Encypt
NSString *stringData = @"Hello Testing";
NSLog(@"encryptedData Data = %@",stringData);
NSData *encryptedData = [self wrapSymmetricKey:[stringData dataUsingEncoding:NSUTF8StringEncoding] keyRef:publicKeyRef];

}


- (NSData *)wrapSymmetricKey:(NSData *)symmetricKey keyRef:(SecKeyRef)publicKey {
OSStatus sanityCheck = noErr;
size_t cipherBufferSize = 0;
size_t keyBufferSize = 0;

LOGGING_FACILITY( symmetricKey != nil, @"Symmetric key parameter is nil." );
LOGGING_FACILITY( publicKey != nil, @"Key parameter is nil." );

NSData * cipher = nil;
uint8_t * cipherBuffer = NULL;

// Calculate the buffer sizes.
cipherBufferSize = SecKeyGetBlockSize(publicKey);
keyBufferSize = [symmetricKey length];

// Allocate some buffer space. I don't trust calloc.
cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t) );
memset((void *)cipherBuffer, 0x0, cipherBufferSize * sizeof(uint8_t));
SecPadding          padding = kSecPaddingNone;
// Encrypt using the public key.
sanityCheck = SecKeyEncrypt(    publicKey,
                            padding,
                            (const uint8_t *)[symmetricKey bytes],
                            keyBufferSize,
                            cipherBuffer,
                            &cipherBufferSize
                            );

LOGGING_FACILITY1( sanityCheck == noErr, @"Error encrypting, OSStatus == %d.", sanityCheck );

// Build up cipher text blob.
cipher = [NSData dataWithBytes:(const void *)cipherBuffer length:(NSUInteger)cipherBufferSize];

if (cipherBuffer) free(cipherBuffer);

return cipher;
}

0 个答案:

没有答案