Page 1 of 1

Erstellen einer Identität aus einem Zertifikat und einem privaten Schlüssel auf iOS (SecItemAdd, SecCertificateCreateWit

Posted: 18 Jan 2025, 22:10
by Guest
Auf einer nativen React-App versuche ich, einen bestimmten und seinen privaten Schlüssel zum iOs-Keystone hinzuzufügen, also versuche ich es mit dem folgenden Code, aber ich habe einen Fehler mit SecItemAdd, wenn ich versuche, den privaten Schlüssel hinzuzufügen (Fehler -50). .

Wie Sie im Code unten und anhand der Informationen, die ich erhalten konnte, sehen können, bereinige ich dank des StripPEMHeader die ursprünglichen Zeichenfolgen von ihrem ANFANG/ENDE und transformiere die Zeichenfolgen dann in NSData.

Wie geht das richtig?

Code: Select all

- (SecIdentityRef)createIdentityWithCert:(NSString *)pemCert privateKey:(NSString *)pemKey {
RCTLogWarn(@"createIdentity: Starting identity creation");

// Strip PEM headers and convert to data
NSString *cleanedCert = [self stripPEMHeader:pemCert prefix:@"CERTIFICATE"];
NSString *cleanedKey = [self stripPEMHeader:pemKey prefix:@"PRIVATE KEY"];

//    RCTLogWarn(@"createIdentity: Cleaned cert length: %lu, key length: %lu",
//               (unsigned long)cleanedCert.length,
//               (unsigned long)cleanedKey.length);

NSData *certData = [[NSData alloc] initWithBase64EncodedString:cleanedCert
options:NSDataBase64DecodingIgnoreUnknownCharacters];
NSData *keyData = [[NSData alloc] initWithBase64EncodedString:cleanedKey
options:NSDataBase64DecodingIgnoreUnknownCharacters];

if (!certData || !keyData) {
RCTLogWarn(@"createIdentity: Failed to create data from base64");
return NULL;
}

// First, generate key pair and store private key
NSDictionary *keyAttributes = @{
(__bridge id)kSecAttrKeyType: (__bridge id)kSecAttrKeyTypeRSA,
(__bridge id)kSecAttrKeyClass: (__bridge id)kSecAttrKeyClassPrivate,
(__bridge id)kSecValueData: keyData,
(__bridge id)kSecAttrKeySizeInBits: @2048,
(__bridge id)kSecAttrIsPermanent: @YES,
(__bridge id)kSecAttrApplicationTag: [@"com.yourdomain.app.key" dataUsingEncoding:NSUTF8StringEncoding]
};

OSStatus status = SecItemAdd((__bridge CFDictionaryRef)keyAttributes, NULL);
if (status != errSecSuccess && status != errSecDuplicateItem) {
RCTLogWarn(@"createIdentity: Failed to store private key, status: %d", (int)status);
return NULL;
}

// Create certificate reference
SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData);
if (!cert) {
RCTLogWarn(@"createIdentity: Failed to create certificate from data");
return NULL;
}

// Store certificate in keychain
NSDictionary *certAttributes = @{
(__bridge id)kSecClass: (__bridge id)kSecClassCertificate,
(__bridge id)kSecValueRef: (__bridge id)cert,
(__bridge id)kSecAttrIsPermanent: @YES
};

status = SecItemAdd((__bridge CFDictionaryRef)certAttributes, NULL);
if (status != errSecSuccess && status != errSecDuplicateItem) {
RCTLogWarn(@"createIdentity: Failed to store certificate, status: %d", (int)status);
if (cert) CFRelease(cert);
return NULL;
}

// Query for the identity
NSDictionary *identityQuery = @{
(__bridge id)kSecClass: (__bridge id)kSecClassIdentity,
(__bridge id)kSecReturnRef: @YES,
(__bridge id)kSecMatchLimit: (__bridge id)kSecMatchLimitOne
};

SecIdentityRef identity = NULL;
status = SecItemCopyMatching((__bridge CFDictionaryRef)identityQuery, (CFTypeRef *)&identity);

if (status != errSecSuccess || !identity) {
RCTLogWarn(@"createIdentity: Failed to find identity, status: %d", (int)status);
} else {
RCTLogWarn(@"createIdentity: Successfully found identity");
}

if (cert) CFRelease(cert);

return identity;
}