Comment puis-je obtenir SecKeyRef de DER/fichier PEM
J'ai besoin d'intégrer mon iPhone avec un système, et ils ont besoin de chiffrer des données à une clé publique, il y a 3 fichiers 3 format différent .xml .der et .pem, j'ai fait des recherches et trouvé quelques articles sur la prise en SecKeyRef de DER/PEM, mais ils sont toujours retourner nil. Ci-dessous mon code:
NSString *pkFilePath = [[NSBundle mainBundle] pathForResource:@"PKFile" ofType:@"der"];
NSData *pkData = [NSData dataWithContentsOfFile:pkFilePath];
SecCertificateRef cert;
cert = SecCertificateCreateWithData(NULL, (CFDataRef) pkData);
assert(cert != NULL);
OSStatus err;
if (cert != NULL) {
err = SecItemAdd(
(CFDictionaryRef) [NSDictionary dictionaryWithObjectsAndKeys:
(id) kSecClassCertificate, kSecClass,
(id) cert, kSecValueRef,
nil
],
NULL
);
if ( (err == errSecSuccess) || (err == errSecDuplicateItem) ) {
CFArrayRef certs = CFArrayCreate(kCFAllocatorDefault, (const void **) &cert, 1, NULL);
SecPolicyRef policy = SecPolicyCreateBasicX509();
SecTrustRef trust;
SecTrustCreateWithCertificates(certs, policy, &trust);
SecTrustResultType trustResult;
SecTrustEvaluate(trust, &trustResult);
if (certs) {
CFRelease(certs);
}
if (trust) {
CFRelease(trust);
}
return SecTrustCopyPublicKey(trust);
}
}
return NULL;
Problème se pose à SecCertificateCreateWithData, il est toujours retourner nil même par lire le fichier est ok.
Quelqu'un a fait cela s'il vous plaît aidez-moi, merci!
EDIT: Le cert fichier MD5 signature.
- Je pense que vous trouverez votre réponse ici: stackoverflow.com/questions/1595013/...
Vous devez vous connecter pour publier un commentaire.
J'ai eu beaucoup de mal avec le même problème et a finalement trouvé une solution. Mon problème était que j'avais besoin d'utiliser un externe privée et une clé publique pour le chiffrement/déchiffrement des données dans une application iOS et je ne voulais pas utiliser le trousseau.
Il s'avère que vous avez également besoin d'un certificat signé pour le iOS la bibliothèque de sécurité pour être en mesure de lire les données de la clé et bien sûr, les fichiers doivent être dans le format correct.
La procédure est essentiellement comme suit:
Dire que vous avez une clé privée au format PEM (avec l' -----BEGIN RSA PRIVATE KEY----- et -----END RSA PRIVATE KEY----- marqueurs): rsaPrivate.pem
Maintenant, vous avez deux fichiers qui sont compatibles avec l'iOS cadre de sécurité: rsaCert.der (clé publique) et rsaPrivate.p12 (clé privée). Le code ci-dessous se lit dans la clé publique en supposant que le fichier est ajouté à votre bundle:
À lire dans la clé privée d'utiliser le code suivant:
À partir de l'iOS 10, il est effectivement possible d'importer des PEM privé touches w/s de les convertir à PKCS#12 (qui est un très universel format de conteneur pour tout ce qui concerne la cryptographie) et donc w/o à l'aide d'OpenSSL sur la ligne de commande ou de la liaison statique des applications avec elle. Sur macOS, il est même possible depuis 10.7 à l'aide d'une fonction différente que ceux mentionnés ici (mais jusqu'à présent, il n'existe pas pour iOS). Exactement de la manière décrite ci-dessous sera également travailler sur macOS 10.12 et plus tard, bien que.
Pour importer un certificat, il suffit de simplement enlever la
et
lignes, puis exécutez un décodage base64 sur les données de la gauche, le résultat est un certificat standard format DER, qui peut simplement être nourris à
SecCertificateCreateWithData()
pour obtenir unSecCertificateRef
. Cela a toujours été de travail, avant l'iOS 10.Pour importer une clé privée, un peu de travail supplémentaire peut être nécessaire. Si la clé privée est enveloppé avec
alors il est très facile. Encore une fois, la première et la dernière ligne doit être dépouillé, le reste des données doit être en base64 décodé et le résultat est une clé RSA dans PKCS#1 format. Ce format ne peut détenir les clés RSA et il est directement lisible, juste nourrir les données décodées dans
SecKeyCreateWithData()
pour obtenir unSecKeyRef
. Leattributes
dictionnaire juste besoin de paires clé/valeur:kSecAttrKeyType
:kSecAttrKeyTypeRSA
kSecAttrKeyClass
:kSecAttrKeyClassPrivate
kSecAttrKeySizeInBits
:CFNumberRef
avec le nombre de bits de la clé (par exemple, 1024, 2048, etc.) Si vous ne connaissez pas, cette information peut être lu à partir de la clé brute des données, qui est à l'ASN.1 les données (c'est un peu au-delà de la portée de cette réponse, mais je vais donner quelques liens utiles ci-dessous sur la façon de traiter ce format). Cette valeur est peut-être en option! Dans mes tests, il n'était pas nécessaire de définir cette valeur; s'il est absent, l'API déterminé la valeur de sa propre et il a toujours été correctement réglé plus tard.Dans le cas où la clé privée est enveloppé par
-----BEGIN PRIVATE KEY-----
, puis les données encodées en base64 n'est pas dans PKCS#1 format mais en PKCS#8 format, cependant, c'est qu'un conteneur générique qui peut également détenir des clés RSA mais pour des clés RSA de l'intérieur des données de ce récipient est égal à PKCS#1, donc, on pourrait dire pour des clés RSA PKCS#8 est PKCS#1 avec un en-tête supplémentaire et tout ce que vous devez faire est de décapage que l'en-tête supplémentaire. Simplement enlever les 26 premiers octets de la base64 données décodées et vous avez PKCS#1 de nouveau. Oui, c'est vraiment aussi simple que cela.Pour en savoir plus sur PKCS#x formats PEM encodages, jetez un oeil à ce site. Pour en savoir plus à propos de l'ASN.Format de 1, voici un bon site pour cela. Et si vous avez besoin d'un simple, mais puissant et interactif en ligne de l'ASN.1 analyseur de jouer avec différents formats, que l'on peut lire directement PEM de données, ainsi que de l'ASN.1 en base64 et hexdump, essayez ce site.
Très important: Lors de l'ajout d'une clé privée pour le trousseau, que vous avez créé comme ci-dessus, s'il vous plaît être conscient que de tels une clé privée ne contient pas une clé publique de hachage, encore une clé publique de hachage est important pour elles de keychain de l'API pour se forger une identité (
SecIdentityRef
), comme à l'aide de la clé publique de hachage est de savoir comment l'API trouve la bonne clé privée qui appartient à un certificat importé (unSecIdentityRef
est juste unSecKeyRef
d'une clé privée et uneSecCertificateRef
d'un cert formant un objet et c'est la clé publique de hachage, qui les lie). Ainsi, lorsque vous plan pour ajouter la clé privée pour le trousseau, assurez-vous de définir une clé publique de hachage manuellement, sinon vous ne sera jamais en mesure d'obtenir une identité pour lui et sans que vous ne pouvez pas utiliser trousseau API pour des tâches comme la signature ou le déchiffrement des données. La clé publique de hachage doit être stocké dans un attribut nommékSecAttrApplicationLabel
(nom stupide, je sais, mais c'est vraiment pas une étiquette et rien que l'utilisateur peut jamais voir, consultez la documentation). E. g.:initWithBase64EncodedString:options:
suffit d'utiliser l'optionNSDataBase64DecodingIgnoreUnknownCharacters
. 3ème partie base64 décodeurs ignorer les retours à la ligne par défaut et qui ne peut être activé par une option.Après des heures d'effort des recherches en ligne, avec l'aide de ce post, je reçois enfin il fonctionne parfaitement. Voici les notes de travail avec le code Swift de la version la plus récente. J'espère que cela peut aider quelqu'un!
Reçu un certificat de la chaîne encodée en base64 pris en sandwich entre en-tête et la queue qui ressemble à ceci (format PEM):
dépouiller l'en-tête et la queue, comme
décodage base64 chaîne de NSData:
Convertir de NSdata format SecCertificate:
Maintenant, ce cert peut être utilisé pour comparer avec le certificat reçu de la urlSession confiance: