Présentation de CryptoKit | raywenderlich.com

Online Coding Courses for Kids

La nouvelle API CryptoKit d’Apple vous permet d’authentifier et de crypter les données envoyées et reçues par votre application, si votre application a besoin de plus que la protection matérielle et logicielle par défaut d’Apple.

Dans cet article, vous allez authentifier et crypter les données à la fois avec une clé symétrique et une cryptographie à clé publique. Vous apprendrez quand et comment utiliser:

  • Hachage cryptographique
  • Code d’authentification de message basé sur le hachage (HMAC)
  • Chiffrement authentifié avec données associées (AEAD) chiffrements
  • Cryptographie à clé publique avec courbes elliptiques (ECC)
  • Signatures numériques
  • Accord clé

Continuez à lire pour découvrir tous les secrets!

Alerte spoil: Ce didacticiel suppose que vous êtes familier avec la série Harry Potter de J.K. Rowling ou n’ont aucun intérêt à le lire. Il discute des secrets révélés dans les derniers livres.

Commencer

Commencez par télécharger les documents de cet article – vous pouvez trouver le lien en haut ou en bas de cet article. Ouvrez, créez et exécutez le Gardien du secret projet dans le entrée dossier.

Application SecretKeeper

Application SecretKeeper

Cette application est une liste de Les horcruxes de Voldemort. Tant qu’une partie de son âme est en sécurité dans l’un de ces objets, Voldemort ne peut pas être tué. Il doit donc garder le secret de leur identité et de leur emplacement pour tout le monde, en particulier Albus Dumbledore et Harry Potter.

Protéger les données des utilisateurs

À l’instar des secrets de Voldemort, les données de vos utilisateurs doivent être protégées contre la corruption accidentelle ou malveillante et contre l’utilisation non autorisée. iOS a déjà beaucoup de sécurité intégrée ou facile à utiliser dans Foundation / NSData, Security / Keychain et CloudKit. Vous bénéficiez gratuitement du cryptage TLS et de la signature numérique si votre application accède aux serveurs HTTPS. Et maintenant, il y a CryptoKit, si votre application doit vérifier les données ou authentifier les expéditeurs.

Vous devez protéger les données dans chacun de ces trois états:

  • Données en mouvement: en transit, généralement sur un réseau
  • Données utilisées: en mémoire
  • > Données au repos: stockées sur disque, non utilisées

Données en mouvement est la raison initiale du chiffrement, remontant à avant le Chiffre César pour avoir envoyé des ordres écrits aux généraux de César. De nos jours, le chiffrement est géré par Transport Layer Security (TLS) si votre application communique avec un serveur à l’aide de TLS 1.3. Mais vous devrez peut-être toujours authentifier les données et l’expéditeur avec un hachage cryptographique et des signatures à clé. La plupart de ce didacticiel porte sur ces sujets.

Données utilisées doit être protégé par l’authentification de l’utilisateur. Pour restreindre le moment où une opération peut être exécutée, utilisez Authentification locale pour vérifier quand et comment l’utilisateur s’est authentifié. Par exemple, vous pouvez demander à l’utilisateur de s’authentifier avec la biométrie – Face ID ou Touch ID – pour s’assurer que l’utilisateur est présent.

Données au repos est protégé sur l’appareil par l’API de protection des données. Les utilisateurs bénéficient d’une protection logicielle automatique des données dès qu’ils définissent un code d’accès pour l’appareil. Chaque nouveau fichier reçoit une nouvelle clé de chiffrement 256 bits, spécifique au type de protection du fichier. Il existe trois types de protection de fichier:

  • Protégé jusqu’à l’authentification du premier utilisateur: Le type de protection de fichier par défaut. Le fichier n’est pas accessible pendant le démarrage de l’appareil, mais il est ensuite accessible jusqu’au redémarrage de l’appareil, même lorsque l’appareil est verrouillé.
  • Achevée: Le fichier n’est accessible que lorsque l’appareil est déverrouillé.
  • Terminé sauf ouvert: Si le fichier est ouvert lorsque l’appareil se verrouille, il est toujours accessible. Si le fichier n’est pas ouvert lorsque l’appareil se verrouille, il n’est pas accessible tant que l’appareil ne se déverrouille pas.

Vous souhaiterez peut-être autoriser l’accès à un fichier lorsque l’appareil est verrouillé pour permettre aux transferts réseau de continuer.

Votre application peut également stocker des données chiffrées dans une base de données CloudKit privée, où elles sont disponibles sur tous les appareils de l’utilisateur.

Augmenter la protection des secrets de Voldemort

SecretKeeper lit un fichier pour créer la liste des horcruxes. L’application écrit ce fichier sans option de protection de fichier:

try data.write(to: secretsURL)

Cela signifie que le fichier secrets ne dispose que de la protection de fichier par défaut, il est donc accessible lorsque l’application est en arrière-plan et même lorsque l’appareil est verrouillé.

Les secrets de Voldemort nécessitent un niveau de protection des fichiers plus élevé. Dans ContentView.swift, dans writeFile(items:), remplace le data.write(to:) déclaration avec cette ligne:

try data.write(to: secretsURL, options: .completeFileProtection)

Avec ce niveau de protection, le fichier n’est accessible que lorsque l’appareil est déverrouillé.

Porte-clés et Secure Enclave

Votre application doit stocker les clés de chiffrement, les jetons d’authentification et les mots de passe dans le local ou sur iCloud Porte-clés. Exemple d’application d’Apple Stockage des clés CryptoKit dans le trousseau montre comment convertir les types de clés CryptoKit P256, P384 et P521 en SecKey et d’autres types de clés aux mots de passe génériques.

Les appareils iOS sortis depuis fin 2013 – iPhone 5S, iPad Air et modèles ultérieurs – ont le Enclave sécurisée puce. Secure Enclave est un moteur de cryptographie dédié, distinct du processeur, avec la clé de cryptage 256 bits de l’identifiant unique (UID) de l’appareil fusionnée en usine. Le Secure Enclave stocke également des données biométriques pour TouchID et FaceID.

Les clés et les données du Secure Enclave ne le quittent jamais. Ils ne sont jamais chargés en mémoire ou écrits sur le disque, ils sont donc complètement protégés. Votre application communique avec Secure Enclave via une boîte aux lettres, où vous déposez des données à chiffrer ou déchiffrer, puis récupérez les résultats.

CryptoKit permet à votre application de créer une clé pour la cryptographie à clé publique directement dans Secure Enclave. Un exemple de code se trouve à la fin de ce didacticiel.

Utilisation de CryptoKit

Toute cette protection des données intégrée peut être tout ce dont votre application a besoin. Ou, vous devrez peut-être utiliser CryptoKit si votre application fonctionne avec des données cryptées par des tiers ou authentifie les transferts de fichiers ou les transactions financières.

Rouler votre propre crypto: pas

La sécurité des données est un champ de bataille entre les cryptographes et les attaquants. À moins que vous ne soyez un cryptographe, écrire vos propres algorithmes cryptographiques représente un risque énorme pour les données de vos utilisateurs. Il existe de nombreux frameworks de cryptographie pour différentes plates-formes. Et maintenant, vous disposez du CryptoKit d’Apple, ce qui facilite l’utilisation de la cryptographie dans vos applications.

Performance: ne vous inquiétez pas

Et les performances? CryptoKit est construit au-dessus de corecrypto, La bibliothèque cryptographique native d’Apple. Le code d’assemblage réglé à la main de Corecrypto permet une utilisation très efficace du matériel.

Hashing cryptographique

Passons maintenant à la forme la plus élémentaire de cryptographie. Vous connaissez probablement l’idée de hacher des éléments de dictionnaire ou des enregistrements de base de données pour une récupération plus efficace. De nombreux types standards conforme à la Hashable protocole. Hachage d’objets de ces types dans un Hasher produit des valeurs de hachage entières avec une probabilité raisonnable d’unicité. Une petite modification de l’entrée produit une modification importante de la valeur de hachage.

Hasher utilise une valeur de départ générée de manière aléatoire, de sorte qu’elle produit des valeurs de hachage différentes à chaque exécution de votre application. Voyez cela par vous-même.

Ouvert CryptoKitTutorial.playground dans le dossier de démarrage. La première section, Protocole hashable, a ceci hashItem(item:) fonction:

func hashItem(item: String) -> Int {
  var hasher = Hasher()
  item.hash(into: &hasher)
  return hasher.finalize()
}

Essayez-le en ajoutant cette ligne en dessous:

let hashValue = hashItem(item: "the quick brown fox")

Exécutez le terrain de jeu. La valeur de hachage apparaît dans la barre latérale des résultats ou cliquez sur l’icône Afficher le résultat bouton pour l’afficher dans l’aire de jeux:

Valeur de hachage Hasher

Valeur de hachage Hasher

Votre valeur est différente de la mienne. Relancez le terrain de jeu et vous obtiendrez une valeur différente.

contrairement à Hasher, hachage cryptographique produit la même valeur de hachage à chaque fois. Comme le Hasher algorithme, les algorithmes de hachage cryptographique produisent des valeurs de hachage presque uniques, et une petite modification de l’entrée produit une grande modification de la valeur de hachage. La différence est celle du degré et de la quantité de calcul nécessaire pour produire une valeur de hachage – appelée digérer ou somme de contrôle – qui peut vérifier de manière fiable l’intégrité des données.

Les algorithmes de hachage cryptographique créent une valeur de données petite, de longueur fixe, presque unique (résumé) pour les données d’entrée. Les tailles de résumé les plus courantes sont de 256 et 512 bits. Le résumé de 512 bits peut être tronqué à 384 bits. Trouver deux entrées qui produisent le même condensé est très peu probable mais pas impossible, car il n’y en a, respectivement, que 2256 ou 2512 valeurs possibles pour un condensé de 256 ou 512 bits.

Les algorithmes de hachage sont une manière et inclure des opérations non linéaires, afin que les attaquants ne puissent pas inverser les opérations pour calculer les données d’origine à partir du condensé. Chaque bit de la sortie dépend de chaque bit de l’entrée, de sorte que les attaquants ne peuvent pas essayer de calculer une partie de l’entrée à partir d’une partie du résumé. Changer ne serait-ce qu’un seul bit dans l’entrée produit un résumé complètement différent, de sorte que les attaquants ne peuvent pas trouver de relations entre les entrées et les sorties.

Le condensé cryptographique est presque unique et très difficile à inverser.

Le condensé cryptographique est presque unique et très difficile à inverser.

Ces caractéristiques vous permettent de voir si deux ensembles de données sont différents en calculant des résumés. Par exemple, Git calcule un condensé pour identifier chaque commit. Vous pouvez transmettre ou stocker des données avec leur résumé pour détecter les modifications ultérieures telles que la corruption des données. Les téléchargements de logiciels fournissent souvent un résumé, appelé somme de contrôle. Le téléchargeur utilise le même algorithme de hachage pour calculer un condensé des données téléchargées. Si ce résumé ne correspond pas à la somme de contrôle du fichier, le fichier est corrompu ou incomplet.

Le récepteur calcule le condensé pour vérifier que les données sont complètes et non corrompues.

Le récepteur calcule le condensé pour vérifier que les données sont complètes et non corrompues.

CryptoKit fournit le Algorithme de hachage sécurisé 2 (SHA-2) algorithmes SHA-256, SHA-384 et SHA-512. Les nombres indiquent la taille du condensé. Ses Insecure conteneur fournit SHA-1 (160 bits) et MD5 (128 bits) pour une compatibilité descendante avec les services plus anciens. SHA-2 a été publié par le National Institute of Standards and Technology (NIST) des États-Unis et est requis par la loi pour être utilisé dans certaines applications du gouvernement américain.

Dans la cour de récréation, faites défiler jusqu’à cette déclaration:

UIImage(data: data)

Dans la barre latérale des résultats, cliquez sur Afficher le résultat à côté de w 714 h 900 pour voir les données est une image de Harry Potter, âgé d’un an:

Les données sont l'image de bébé Harry Potter.

Les données sont l’image de bébé Harry Potter.

Quand Voldemort n’a pas réussi à tuer Harry, il l’a accidentellement transformé en horcruxe. Mais Voldemort ne le sait pas. Albus Dumbledore le sait, et il veut partager ce secret avec Harry.

Tout d’abord, en tant que Dumbledore, créez un condensé de ces données. Ajoutez cette ligne:

let digest = SHA256.hash(data: data)

C’est tout ce que vous avez à faire! SHA256 produit un condensé de 256 bits. Il est tout aussi simple d’utiliser l’un des deux autres algorithmes de hachage – SHA384 ou SHA512. Et si Apple les met à jour pour les utiliser SHA-3 au lieu de SHA-2, vous n’aurez pas à modifier votre code.

Puis Dumbledore envoie les données et les digère via une connexion réseau à Harry. Alors maintenant, en tant que Harry, ajoutez ce code pour vérifier la correspondance des résumés:

let receivedDataDigest = SHA256.hash(data: data)
if digest == receivedDataDigest { 
  print("Data received == data sent.") 
}

Vous utilisez le même algorithme de hachage sur les données, puis vérifiez que les deux valeurs de résumé sont égales.

Exécutez le terrain de jeu. Le message s’imprime. Pas étonnant, car data n’avait aucune chance de se corrompre.

Cliquez maintenant sur le Afficher le résultat bouton à côté de receivedDataDigest pour avoir un bon aperçu du résumé:

CryptoKit SHA256 résumé des données

CryptoKit SHA256 résumé des données

C’est un tuple. Pas très lisible.

Tapez cette ligne pour afficher son description au lieu:

String(describing: digest)

Remarque: La documentation d’Apple décourage les appels .description directement.

Exécutez le terrain de jeu. Cliquez sur Afficher le résultat:

Description de la chaîne du condensé CryptoKit

Description de la chaîne du condensé CryptoKit

Le digest description contient un String. Ceci est plus lisible par l’homme et ressemble à une valeur de hachage Git, mais deux fois plus longue. C’est aussi beaucoup plus long que le Hasher valeur de hachage.

Enfin, pour voir comment un petit changement dans les données produit un résumé complètement différent, apportez un tout petit changement à l’une des deux lignes de code identiques. Par exemple:

String(describing: SHA256.hash(data: "Harry is a horcrux".data(using: .utf8)!))
String(describing: SHA256.hash(data: "Harry's a horcrux".data(using: .utf8)!))

Exécutez le terrain de jeu. Cliquez sur Afficher le résultat pour les deux lignes:

Les résumés CryptoKit de données presque identiques sont très différents.

Les résumés CryptoKit de données presque identiques sont très différents.

Remarquez que vous obtenez exactement les mêmes valeurs de hachage que j’ai faites.

Signature du résumé

Le hachage des données ne vous protège pas des modifications malveillantes, car un attaquant malveillant enverra simplement le résumé correct de ses données modifiées.

Code d’authentification de message basé sur le hachage (HMAC) protège contre les modifications malveillantes en signature le digest avec un clé cryptographique symétrique. Un cas d’utilisation courant consiste à signer le résumé d’un fichier afin que le serveur de l’application puisse vérifier que vous êtes autorisé à importer des fichiers.

«Clé symétrique» signifie que l’expéditeur et le destinataire connaissent tous deux la clé secrète. HMAC utilise la clé secrète pour dériver les clés internes et externes. Ensuite, il crée un hachage interne à partir des données et de la clé interne. Enfin, il crée le Signature du hachage interne et de la clé externe.

Diagramme du code d'authentification de message haché

Diagramme du code d’authentification de message haché

C’est ce que fait l’algorithme. Mais pour créer une clé symétrique avec CryptoKit, il vous suffit de taper cette ligne:

let key256 = SymmetricKey(size: .bits256)

Beaucoup moins de travail que l’ancienne API de cryptographie C d’Apple, où vous deviez convertir des bits et des octets et n’oubliez pas de supprimer la clé de la mémoire lorsque vous avez terminé!

L’attaque la plus courante contre HMAC est la force brute pour découvrir la clé secrète, de sorte que la sécurité de HMAC dépend de la taille de la clé secrète. CryptoKit autorise trois tailles de clé: .bits128, .bits192 et .bits256.

Ensuite, ajoutez ces deux instructions de code:

let sha512MAC = HMAC.authenticationCode(
  for: data, using: key256)
String(describing: sha512MAC)

Vous créez le résumé pour data en utilisant votre clé symétrique, donc maintenant le résumé s’appelle un code d’identification ou Signature.

Exécutez le terrain de jeu. Cliquez sur Afficher le résultat pour voir la description de la signature:

Description de la signature CryptoKit HMAC 512 bits

Description de la signature CryptoKit HMAC 512 bits

Vous avez produit une signature de 512 bits (64 octets) pour l’image de bébé.

Pour envoyer cette signature sur le réseau, convertissez-la en Data:

let authenticationCodeData = Data(sha512MAC)

Maintenant, Dumbledore vous envoie les données signées en tant que Harry. Vous-comme-Harry avez déjà le même clef secrète key256. Saisissez ce code pour authentifier ce que vous avez reçu:

if HMAC.isValidAuthenticationCode(authenticationCodeData,
   authenticating: data, using: key256) {
    print("The message authentication code is validating the data: (data))")
  UIImage(data: data)
}
else { print("not valid") }

Si la signature est valide, vous, en tant qu’Harry, visualisez les données, sachant que c’est vraiment ce que Dumbledore a envoyé.

Exécutez le terrain de jeu. Cliquez sur Afficher le résultat à côté de la print déclaration et à côté du UIImage:

CryptoKit authentifiant la signature et les données HMAC

CryptoKit authentifiant la signature et les données HMAC

HMAC vous permet de vérifier l’identité de l’expéditeur et l’intégrité des données, mais ne crypte pas les données. Si vous oubliez d’utiliser TLS et que Voldemort intercepte la transmission, il soupçonnera qu’Harry est l’un de ses horcruxes.

Ou Voldemort pourrait décider de crypter manuellement sa liste d’horcruxes, pour être absolument sûr que Dumbledore et Harry ne peuvent pas les trouver et les détruire.

Le cryptage des données est ce qu’est la cryptographie, alors le voici.

Chiffrement et authentification des données

Même avec les données réseau de cryptage TLS, vous souhaiterez peut-être envoyer des fichiers cryptés aux utilisateurs. Par exemple, s’ils ont effectué un achat via l’application, vous leur enverrez le fichier chiffré et (séparément) la clé pour le déchiffrer.

L’état actuel de la technique est un cryptage authentifié avec des données associées (AEAD) chiffrement. Un chiffrement AEAD utilise différentes clés pour le chiffrement et le MAC, et le MAC hache le texte chiffré, pas le texte brut. Tout est combiné en un boîte scellée.

Il existe deux AEAD couramment utilisés: Advanced Encryption Standard Galois / Counter Mode (AES-GCM) et ChaCha20-Poly1305. Les deux sont nouveaux dans l’API de cryptographie d’Apple. AES-GCM est la norme établie par le NIST. Daniel J. Bernstein a développé ChaCha20-Poly1305 au cas où un attaquant parviendrait à briser AES-GCM.

En 2019, presque tout le trafic TLS utilisait AES, mais ChaCha20-Poly1305 gagne en popularité car il est beaucoup plus rapide que AES-GCM sur les appareils mobiles qui ne prennent pas en charge AES-GCM. Mais n’hésitez pas à utiliser AES-GCM dans vos applications, car les appareils iOS ont du matériel AES:].

AES et ChaCha20 sont des algorithmes de chiffrement. GCM et Poly1305 sont des algorithmes MAC. Bernstein a développé ChaCha20 à partir de son premier chiffre Salsa. ;]

Pour créer une boîte scellée, un chiffrement AEAD prend ces entrées:

  1. Texte en clair à chiffrer
  2. Une clé secrète
  3. Une valeur d’initialisation unique – IV ou nonce: Cela empêche les attaques de relecture, comme quelqu’un (qui vraiment doit avoir une vie) renvoyer plusieurs fois la même commande de panier.
  4. Facultatif: données non secrètes supplémentaires, authentifiées mais non chiffrées. C’est le UN D dans AEAD.

Puis le joint opération:

  1. Utilise la clé et le nonce pour générer une clé secondaire.
  2. Utilise la clé et le nonce pour crypter les données en données cryptées de longueur égale – le ciphertext.
  3. Utilise la clé secondaire pour générer un résumé codé de toutes les données supplémentaires, les données chiffrées et la longueur de chacune.
  4. Utilise la clé et le nonce pour crypter le résumé à clé, puis ajoute le résumé à clé crypté aux données cryptées.

J’ai omis le données associées dans ce diagramme:

Schéma du fonctionnement du joint CryptoKit Sealed Box

Schéma du fonctionnement du joint CryptoKit Sealed Box

Cela ressemble à beaucoup de travail, n’est-ce pas? Eh bien, voici tout tu besoin de taper, pour créer une boîte scellée:

let sealedBoxData = try! ChaChaPoly.seal(data, using: key256).combined

Vous fournissez les données et la clé pour obtenir une boîte scellée. Ses combined la propriété est de type Data, que vous pouvez envoyer sur le réseau.

Pour utiliser AES-GCM à la place, vous devez remplacer ChaChaPoly avec AES.GCM.

Maintenant, Dumbledore envoie les données de la boîte scellée à Harry. Vous-comme-Harry tapez ce code pour le transformer en une boîte scellée:

let sealedBox = try! ChaChaPoly.SealedBox(combined: sealedBoxData)

Vous-en-tant-qu’Harry avez déjà la même clé secrète que Dumbledore, vous pouvez donc ouvrir la boîte scellée et décrypter sa ciphertext:

let decryptedData = try! ChaChaPoly.open(sealedBox, using: key256)

Exécutez le terrain de jeu.

Code CryptoKit pour le sceau ChaChaPoly et les opérations ouvertes

Code CryptoKit pour le sceau ChaChaPoly et les opérations ouvertes

Notez la taille de sealedBoxData est 28 octets de plus que les données d’image. Ajoutez ces lignes pour voir ce qu’il y a d’autre dans la boîte scellée:

sealedBox.nonce  // 12 bytes
sealedBox.tag  // 16 bytes
Tailles et contenu de la boîte scellée CryptoKit nonce et étiquette

Tailles et contenu de la boîte scellée CryptoKit nonce et étiquette

Les deux algorithmes sélectionnent un nonce pour vous, puis emballez-le dans la boîte scellée pour open utiliser. Si facile! Le 16 octets tag est le condensé chiffré à clé – la signature qui authentifie les données. Le nonce change à chaque fois que vous créez la boîte scellée, ce qui modifie également le résumé chiffré à clé. Donc votre réel nonce et tag les valeurs ne correspondent pas à ma capture d’écran.

Enfin, juste pour prouver que les données chiffrées ne peuvent pas être visualisées, ajoutez ces lignes:

let encryptedData = sealedBox.ciphertext
UIImage(data: encryptedData)
UIImage(data: decryptedData)

Exécutez le terrain de jeu. Afficher le résultat pour les deux lignes:

Les données chiffrées ne peuvent pas être affichées comme UIImage.

Les données chiffrées ne peuvent pas être affichées comme UIImage.

Il est facile d’envoyer des données chiffrées, mais l’expéditeur et le destinataire doivent connaître la clé secrète. Et si ce n’est pas possible?

Cryptographie à clé publique

Remarque: Cela fait toujours partie de CryptoKit, mais c’est un sujet assez important, il a donc sa propre section.

Le cryptage HMAC et Sealed Box utilise des clés symétriques, dans lesquelles l’expéditeur et le destinataire connaissent tous deux la clé. Les clés symétriques doivent être transmises «hors bande». Si vous ne pouvez pas le faire en toute sécurité, vous utilisez la cryptographie à clé publique. En fait, la plupart des cryptages de routine sur Internet utilisent la cryptographie à clé publique, y compris chaque fois que Xcode signe votre application.

La cryptographie à clé publique crée deux clés liées mathématiquement. Vous gardez votre clé privée secrète et publiez les données de clé publique correspondantes. Vous signez les données ou leur résumé avec votre clé privée, puis vous les envoyez. Le récepteur crée une clé publique à partir de vos données de clé publique, puis l’utilise pour vérifier les données signées ou le condensé.

Par exemple, votre application peut avoir besoin d’authentifier une opération avec votre serveur principal. Sur l’appareil de l’utilisateur, il crée une clé privée dans laquelle il stocke Keychain ou SecureEnclave, puis enregistre la clé publique correspondante sur le serveur. Lorsque votre utilisateur configure l’opération, votre application signe les détails de l’opération avec la clé privée de l’utilisateur et envoie les détails signés au serveur, qui le vérifie avec la clé publique de l’utilisateur.

Pour envoyer des données chiffrées, vous et votre destinataire créez chacun une paire de clés et publiez les clés publiques. Vous combinez ensuite tous les deux votre clé privée avec la clé publique de l’autre pour créer un secret partagé. Vous utilisez tous les deux ce secret partagé pour dériver la même clé symétrique, que vous pouvez ensuite utiliser pour AEAD comme décrit dans la section précédente.

Création de clés privées et publiques

La principale caractéristique de la cryptographie à clé publique est qu’elle utilise algorithmes de trappe: Il est très très difficile de calculer la clé privée à partir de la clé publique.

Après sa publication en 1978, RSA (Rivest-Shamir-Adleman) est devenu l’algorithme à clé publique le plus populaire. Elle repose sur la difficulté de déterminer les deux facteurs de nombres premiers d’un très, très, très grand nombre. D’autres mathématiciens ont relevé le défi, développant des algorithmes d’affacturage qui ne pouvaient être tenus à distance qu’en augmentant la taille des clés. La génération de clés RSA est lente et le temps augmente avec la taille de la clé. Finalement, les algorithmes d’affacturage se sont améliorés plus rapidement que la puissance des appareils mobiles pour calculer avec de très grands nombres. L’attention s’est tournée vers une autre technologie, qui s’avère beaucoup plus difficile à attaquer.

ECC (Elliptic Curve Cryptography), suggérée pour la première fois en 1985, est largement utilisée depuis 2004 et est devenue la technologie préférée sur les serveurs à la fin de 2015. Les clés ECC sont beaucoup plus petites que les clés RSA avec une sécurité similaire: par exemple, la sécurité d’un 256 La clé publique ECC -bit est comparable à une clé publique RSA de 3072 bits.

CryptoKit utilise exclusivement des algorithmes ECC. Vos options ici sont celles du NIST P256 / P384 / P521 ou Daniel J. Bernstein Courbe25519. P256 est de loin la courbe la plus utilisée. C’est la courbe par défaut pour OpenSSL, où elle est connue sous le nom prime256v1. P384 nécessite 2 à 3 fois plus de calculs que P256. La National Security Agency (NSA) des États-Unis exige le P384 pour protéger les informations top-secrètes. P256 et P384 sont dans la NSA Cryptographie Suite B, mais P521 ne l’est pas, et je n’ai trouvé aucune information sur les utilisateurs. Des super-fantômes, peut-être?

Bernstein a publié Curve25519 la même année que la Suite B de la NSA, mais sa popularité a augmenté après le dénonciateur. Edward Snowden publié des mémos internes en 2013 suggérant que la NSA avait inséré une porte dérobée cryptographique dans le générateur pseudo-aléatoire basé sur la courbe elliptique Dual_EC_DRBG. Tous les deux Dual_EC_DRBG et P256 s’appuient sur Rien dans ma manche (NUMS) nombres magiques. La communauté cryptographique soupçonnait la NSA d’utiliser des valeurs spéciales pour dériver ces nombres magiques, leur permettant de décrypter tout ce qui était crypté avec P256. Curve25519 ne repose pas sur des nombres magiques. Sa complexité de calcul est 40% inférieure à P256. Et la norme TLS 1.3 2018 nécessite une prise en charge.

ECC: comment ça marche?

De nombreux articles, comme celui-là, utilisez l’arithmétique des petits nombres premiers pour expliquer RSA d’une manière facile à comprendre. L’algorithme est assez intelligent.

La cryptographie à courbe elliptique est encore meilleure! Mais un peu plus compliqué à expliquer.

Une courbe elliptique se compose du (x,y) points satisfaisant une équation de cette forme:

y^2 = x^3 + ax + b

Par exemple, y^2 = x^3 - x + 1 ressemble à ça:

Graphique d'une courbe elliptique

Graphique d’une courbe elliptique

Vous pouvez tracer plus de courbes elliptiques à Calculatrice graphique Desmos.

ECC utilise deux propriétés des courbes elliptiques:

  1. Toute ligne non verticale coupe le graphique en trois points au maximum.
  2. Le graphique est symétrique autour du x-axe.

Ces propriétés vous permettent de définir un opération par points entre deux points quelconques du graphique:

  1. Tracez une ligne entre les points A et B.
  2. Là où cette ligne atteint le graphique en un troisième point, réfléchissez sur x-axis pour obtenir le point C = un point B.
courbe elliptique A opération point B

courbe elliptique A opération point B

Vous pouvez également définir le multiplication de points opération k * A, où k est un entier positif.

  1. Commencez par un point A pour obtenir le point B: tracez la ligne tangente à la courbe au point A et réfléchissez sur l’axe des x où cette ligne frappe le graphique. C’est la première opération de point.
  2. Maintenant, faites un point B pour obtenir le point C, puis un point C = D, et ainsi de suite. Faites un total de k opérations de points, se terminant au point P. Si vous dites à quelqu’un où se trouvent les points A et P, c’est vraiment difficile pour eux de calculer k.

L’algorithme actuel utilise uniquement des valeurs entières de x et y, modulo un nombre premier n. Le point de départ est appelé le Générateur, il est donc généralement nommé G. Il a la propriété que n * G = G.

Pour configurer un cryptosystème ECC, vous choisissez une équation de courbe (le coefficient de x et la constante b), un point générateur G sur cette courbe et son nombre premier correspondant n. La clé privée est un nombre sélectionné au hasard k, et la clé publique est k * G – le point final sur la courbe après k opérations de point sur G.

Bien sûr, tu n’a pas besoin de faire quoi que ce soit. Il existe déjà des courbes standard comme Curve25519 et celles utilisées par les ECC NIST, et celles-ci sont implémentées dans les méthodes à clé publique de CryptoKit.

Signatures numériques

Les signatures numériques sont comme HMAC, mais avec une cryptographie à clé publique. Au lieu d’utiliser la même clé secrète pour signer et vérifier, l’expéditeur utilise une clé privée pour signer et le destinataire utilise la clé publique de l’expéditeur pour vérifier.

Cryptographie à clé publique: signez avec une clé privée, vérifiez avec une clé publique.

Cryptographie à clé publique: signez avec une clé privée, vérifiez avec une clé publique.

Les acronymes pour la signature numérique sont Algorithme de signature numérique à courbe elliptique (ECDSA), en utilisant les courbes P256 / P384 / P512 du NIST et l’algorithme de signature numérique à courbe d’Edwards (EdDSA), en utilisant la courbe Ed25519 de Bernstein.

Supposons que vous, en tant que Dumbledore, vouliez envoyer l’image d’horcruxe à Harry. Vous le signerez pour qu’Harry puisse vérifier qu’il s’agit de vous-en-tant-que-Dumbledore. Tout d’abord, vous créez des clés privées et publiques pour la signature numérique:

let albusSigningPrivateKey = Curve25519.Signing.PrivateKey()
let albusSigningPublicKeyData = 
  albusSigningPrivateKey.publicKey.rawRepresentation

le rawRepresentation de la clé publique est de type Data, afin que vous puissiez l’envoyer sur le réseau.

Ensuite, vous-en-tant que Dumbledore utilisez votre clé privée pour signer les données:

let signatureForData = try! albusSigningPrivateKey.signature(for: data)

Ou vous signez le digérer des données, ce qui est plus rapide:

let digest512 = SHA512.hash(data: data)
let signatureForDigest = try! albusSigningPrivateKey.signature(
  for: Data(digest512))

Vous-en-tant que Dumbledore utilisez SHA-512 cette fois.

Lors de l’utilisation d’une clé privée Curve25519, signature(for:) génère une signature d’algorithme de signature numérique à courbe elliptique (EdDSA) des données ou un condensé sur la courbe elliptique Ed25519, en utilisant SHA-512 comme fonction de hachage. Cet algorithme génère un nonce aléatoire pour produire une signature différente à chaque appel, même pour les mêmes données et clés, afin de se prémunir contre les attaques de synchronisation.

Si vous utilisez P256 au lieu de Curve25519, il génère une signature ECDSA (algorithme de signature numérique à courbe elliptique) des données sur la courbe elliptique P-256, en utilisant SHA-256 comme fonction de hachage.

Maintenant vous-en-tant que Dumbledore envoyez data, digest512 et signatureForData ou signatureForDigest à Harry.

En passant à vous-comme-Harry, vous ajoutez ce code pour vérifier les signatures avec une clé créée à partir de albusSigningPublicKeyData.

let publicKey = try! Curve25519.Signing.PublicKey(
  rawRepresentation: albusSigningPublicKeyData)
if publicKey.isValidSignature(signatureForData, for: data) {
  print("Dumbledore sent this data.")
}
if publicKey.isValidSignature(signatureForDigest,
  for: Data(digest512)) {
  print("Data received == data sent.")
  UIImage(data: data)
}

Remarque: P256 et ses frères NIST ont une méthode pour signer un condensé sans le convertir en Data.

Exécutez le terrain de jeu pour voir les données authentifiées:

Code CryptoKit utilisant la clé publique pour vérifier la signature de la clé privée

Code CryptoKit utilisant la clé publique pour vérifier la signature de la clé privée

Et c’est à quel point il est facile de faire des signatures numériques. Mais encore une fois, les données ne sont pas chiffrées. Alors continuez à lire!

Création d’une clé symétrique pour le chiffrement

Plus tôt dans ce tutoriel, Dumbledore et Harry avaient une clé secrète qu’ils connaissaient tous les deux, ce qui leur permettait d’utiliser une boîte scellée AEAD pour crypter et décrypter les données. Mais Voldemort a en quelque sorte découvert cette clé secrète, et il n’est pas possible de définir en toute sécurité une nouvelle clé symétrique – Harry est en fuite et Dumbledore n’est qu’un esprit – alors maintenant, ils doivent trouver un autre moyen.

Les algorithmes d’accord clés leur permettent de créer un secret partagé à partir de leurs clés publiques et privées, puis ajoutez un sel valeur pour générer un clé symétrique.

Schéma de l'algorithme d'accord de clé publique-privée

Schéma de l’algorithme d’accord de clé publique-privée

Calculer le secret partagé est incroyablement simple. Si G est le point générateur de la courbe elliptique, et a est la clé secrète de Dumbledore, alors a * G est sa clé publique. De même, la clé secrète de Harry est h et sa clé publique est h * G. Il s’avère que c’est vrai:

(a * G) * h = (h * G) * a

C’est vrai, Harry multiplie la clé publique de Dumbledore par sa clé privée, et c’est le même point que Dumbledore obtient en multipliant la clé publique de Harry par sa propre clé privée. La magie!

Ici, l’acronyme est Accord de clé ECDH (Elliptic Curve Diffie Hellman), utilisant les courbes P256 / P384 / P512 du NIST ou la courbe X25519 de Bernstein.

Tout d’abord, Dumbledore et Harry créent des clés privées et publiques pour l’accord de clé, et publient leurs clés publiques comme Data.

let albusPrivateKey = Curve25519.KeyAgreement.PrivateKey()
let albusPublicKeyData = albusPrivateKey.publicKey.rawRepresentation
let harryPrivateKey = Curve25519.KeyAgreement.PrivateKey()
let harryPublicKeyData = harryPrivateKey.publicKey.rawRepresentation

Dumbledore et Harry doivent s’entendre sur le valeur du sel pour créer la clé symétrique:

let protocolSalt = "Voldemort's Horcruxes".data(using: .utf8)!

Vous pouvez l’envoyer en toute sécurité sur le réseau. Cela n’aidera pas un attaquant à moins qu’il ne connaisse également l’une des clés privées.

Dumbledore crée la clé publique de Harry à partir de sa représentation brute, puis la combine avec sa clé privée pour calculer d’abord le sharedSecret et puis le symmetricKey:

let harryPublicKey = try! Curve25519.KeyAgreement.PublicKey(
  rawRepresentation: harryPublicKeyData)
let ADsharedSecret = try! albusPrivateKey.sharedSecretFromKeyAgreement(
  with: harryPublicKey)
let ADsymmetricKey = ADsharedSecret.hkdfDerivedSymmetricKey(
  using: SHA256.self, salt: protocolSalt,
  sharedInfo: Data(), outputByteCount: 32)

Harry crée la clé publique de Dumbledore à partir de sa représentation brute, puis la combine avec sa clé privée pour calculer d’abord le sharedSecret et puis le symmetricKey:

let albusPublicKey = try! Curve25519.KeyAgreement.PublicKey(
rawRepresentation: albusPublicKeyData)
let HPsharedSecret = try! harryPrivateKey.sharedSecretFromKeyAgreement(
  with: albusPublicKey)
let HPsymmetricKey = HPsharedSecret.hkdfDerivedSymmetricKey(
  using: SHA256.self, salt: protocolSalt,
  sharedInfo: Data(), outputByteCount: 32)

Maintenant, pour voir s’ils correspondent:

if ADsymmetricKey == HPsymmetricKey {
  print("Dumbledore and Harry have the same symmetric key.")
}

Exécutez le terrain de jeu.

Les clés symétriques dérivées de CryptoKit correspondent.

Les clés symétriques dérivées de CryptoKit correspondent.

Comme par magie, Dumbledore et Harry produisent la même clé symétrique! Ils peuvent désormais utiliser cette clé symétrique pour le cryptage authentifié AEAD.

Clé P256 dans Secure Enclave

Remarque: SecureEnclave Le code ne fonctionne que sur un appareil doté d’une puce Secure Enclave: iPhone 5S, iPad Air et modèles ultérieurs.

Pour une protection supplémentaire, vous pouvez créer P256 clés privées directement dans Secure Enclave de l’appareil. Il s’agit d’une très petite modification du code:

// Check that the device has a Secure Enclave
if SecureEnclave.isAvailable {
  // Generate private key in Secure Enclave
  let privateKey = try SecureEnclave.P256.Signing.PrivateKey() 
} else {
  let privateKey = P256.Signing.PrivateKey()
}

Avec la clé privée dans Secure Enclave, la création des données de clé publique et la signature des données ou du résumé fonctionnent exactement de la même manière:

// Create public key data
let publicKeyData = privateKey.publicKey.compactRepresentation!
// Produce a signature
let dataSignature = try privateKey.signature(for: data)
let digestSignature = try privateKey.signature(for: digest)

Remarque: Vous ne pouvez créer des clés P256 que dans Secure Enclave. Ce mai être parce que la puce contient le moteur AES utilisé par P256 et non parce que le gouvernement américain demande à Apple de fournir une porte dérobée.

Le Secure Enclave a cette fonctionnalité intéressante: vous pouvez contraindre l’utilisation des clés avec contrôle d’accès. Par exemple:

let accessControl = SecAccessControlCreateWithFlags(
  nil,
  kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
  [.privateKeyUsage, .userPresence], 
  nil)!
let privateKey = try SecureEnclave.P256.Signing.PrivateKey(
  accessControl: accessControl)

Vous définissez le contrôle d’accès de sorte que la clé que vous créez dans Secure Enclave ne soit accessible que lorsque l’appareil est déverrouillé et est disponible sur cet appareil uniquement. De plus, votre application nécessite présence des utilisateurs lorsqu’il effectue une opération avec la clé privée. Exiger la présence de l’utilisateur signifie que l’utilisateur doit s’authentifier avec TouchID ou FaceID ou le code d’accès de l’appareil.

Se conformer aux règlements d’exportation de cryptage

Une dernière chose. Le cryptage est une question politique sensible dans de nombreux pays. Cette carte montre quels pays ont des exigences en matière de licences ou d’enregistrement, des contrôles d’importation / exportation, des obligations pour les fournisseurs d’aider les autorités et d’autres restrictions.

Les États-Unis sont l’un des pays avec des contrôles à l’exportation. C’est une question juridique, je vais donc citer directement l’article d’Apple Se conformer aux règlements d’exportation de cryptage:

Lorsque vous soumettez votre application à TestFlight ou à l’App Store, vous téléchargez votre application sur un serveur aux États-Unis. Si vous distribuez votre application en dehors des États-Unis ou du Canada, votre application est soumise aux lois américaines sur l’exportation, quel que soit l’endroit où votre entité juridique est basée. Si votre application utilise, accède, contient, implémente ou incorpore le cryptage, cela est considéré comme une exportation de logiciel de cryptage, ce qui signifie que votre application est soumise aux exigences de conformité des exportations américaines, ainsi qu’aux exigences de conformité à l’importation des pays où vous distribuez votre app.

Et de l’aide de l’App Store Connect d’Apple Présentation de la conformité à l’exportation:

L’utilisation du cryptage comprend, mais sans s’y limiter:

  • Passer des appels via des canaux sécurisés (par exemple HTTPS, SSL, etc.).
  • Utilisation d’algorithmes de cryptage standard.
  • Utilisation de la fonctionnalité cryptographique d’autres sources telles que iOS ou macOS.
  • Utilisation d’algorithmes de chiffrement propriétaires ou non standard. The U.S. Government defines “non-standard cryptography” as any implementation of “cryptography” involving the incorporation or use of proprietary or unpublished cryptographic functionality, including encryption algorithms or protocols that have not been adopted or approved by a duly recognized international standards body ( e.g., IEEE, IETF, ISO, ITU, ETSI, 3GPP, TIA, and GSMA) and have not otherwise been published.

App Store Connect provides a set of questions to help you determine if export compliance documentation is required from you, and which forms are needed.

Where To Go From Here?

Congratulations! You’ve taken a quick tour of all the things CryptoKit can do and learned a little of how cryptography works. And aren’t you glad CryptoKit makes everything so easy?

You can download the completed version of the project using the Download Materials button at the top or bottom of this tutorial.

As always, you can find out more at the source:

In addition to the (mostly Wikipedia) links throughout this tutorial, here’s the explanation of elliptic curve cryptography that really helped me see what was going on:

Close Menu