Opprette digitale signaturer med Swift

Hovedformålet med en digital signatur er å verifisere integriteten til noen opplysninger. For et enkelt eksempel, la oss si at du hadde en fil som ble overført via nettverket, og du vil kontrollere at hele filen ble overført riktig. I så fall vil du bruke et sjekksum.

"En sjekksum er et liten størrelse datasett fra en blokk med digitale data for å oppdage feil som kan ha blitt introdusert under overføring eller lagring" - Wikipedia

Hvordan får vi det sjekksummen? Det beste alternativet er å bruke en hash. En hash-funksjon vil ta en variabel mengde data og vil sende en signatur med fast lengde. For eksempel kan vi publisere en fil sammen med sin hash online. Når noen laster ned filen, kan de deretter kjøre den samme hash-funksjonen på sin versjon av filen og sammenligne resultatet. Hvis hashene er de samme, er den kopierte eller nedlastede filen den samme som originalen. 

En hash er også en enveisfunksjon. Gitt den resulterende produksjonen, er det ingen beregningsmessig mulig måte å reversere isen for å avsløre hva den opprinnelige inngangen var. SHA, Secure Hash Algorithm, er en kjent standard som refererer til en gruppe hashfunksjoner som har denne egenskapen og visse andre, noe som gjør dem nyttige for digitale signaturer..

Om SHA

SHA har gjennomgått mange iterasjoner siden den ble publisert for første gang. Den første og andre iterasjoner, SHA-0 og SHA-1, er nå kjent for å ha store svakheter. De er ikke lenger godkjent for sikkerhetsimplementeringer: de skal vanligvis ikke brukes til applikasjoner som stole på sikkerhet. SHA-2-familien inneholder imidlertid versjoner som heter SHA-256 og SHA-512, og disse anses å være sikre. "256" og "512" refererer ganske enkelt til det resulterende antall produserte biter. For denne opplæringen skal vi bruke SHA-512.

Merk: En annen eldre populær hash-algoritme var MD5. Det ble også funnet å ha betydelige feil.

Bruke SHA er flott for å sjekke om data ble skadet ved et uhell, men dette forhindrer ikke en ondsinnet bruker i å manipulere med dataene. Gitt at en hash-utgang er av en fast størrelse, er alt en angriper nødt til å gjøre, finne ut hvilken algoritme som ble brukt, gitt utgangsstørrelsen, endre dataene og rekomprimere hash. Det vi trenger er noe hemmelig informasjon lagt til blandingen når ishaling av dataene slik at angriperen ikke kan rekomputerer hash uten kjennskap til hemmeligheten. Dette kalles en Hash Message Authentication Code (HMAC).

HMAC

HMAC kan godkjenne et stykke informasjon eller melding for å sikre at den kommer fra den riktige avsenderen og at informasjonen ikke er endret. Et vanlig scenario er når du snakker til en server med en back-end-API for appen din. Det kan være viktig å autentisere for at bare appen din får lov til å snakke med APIen. APIen ville ha adgangskontroll til en bestemt ressurs, for eksempel a / register_user endepunkt. Klienten ville måtte skilt sin forespørsel til / register_user sluttpunkt for å kunne bruke det.

Når du signerer en forespørsel, er det vanlig å ta valgte deler av forespørselen, for eksempel POST-parametere og nettadressen, og bli med dem sammen i en streng. Å ta avtalt elementer og sette dem i en bestemt rekkefølge kalles kanonise. I HMAC er den sammenføyde strengen hakket sammen med den hemmelige nøkkelen til å produsere signatur. I stedet for å kalle det en hash bruker vi begrepet signatur på samme måte som en persons signatur i virkeligheten brukes til å verifisere identitet eller integritet. Signaturen legges tilbake til klientens forespørsel som en forespørselsoverskrift (vanligvis også kalt "Signatur"). En signatur kalles noen ganger en melding fordøyelse, men de to begrepene kan brukes om hverandre.

Over på API-siden gjentar serveren prosessen med å bli med i strengene og skape en signatur. Hvis signaturene samsvarer, viser det at appen må ha besittelse av hemmeligheten. Dette viser identiteten til appen. Siden bestemte parametere av forespørselen også var en del av strengen som skulle signeres, garanterer den også forespørselenes integritet. Det forhindrer en angriper fra å utføre et man-i-midten-angrep, for eksempel, og endre forespørselsparametrene til deres smak.

klassen func hmacExample () // Noen URL-eksempel ... la urlString = "https://example.com" la postString = "id = 123" la url = URL.init (streng: urlString) var request = URLRequest (url: url!) request.httpMethod = "POST" request.httpBody = postString.data (bruk: .utf8) la session = URLSession.shared // Opprett en signatur la stringToSign = request.httpMethod! + "&" + urlString + "&" + postString-utskrift ("Strengen som skal signeres er:", stringToSign) hvis la dataToSign = stringToSign.data (using: .utf8) la signeringSecret = "4kDfjgQhcw4dG6J80QnvRFbtuJfkgitH6phkLN90" hvis la signeringSecretData = signeringSecret .data (bruk: .utf8) la digestLength = Int (CC_SHA512_DIGEST_LENGTH) la digestBytes = UsikkertMutablePointer.allokere (kapasitet: digestLength) CCHmac (CCHmacAlgorithm (kCCHmacAlgSHA512), [UInt8] (signeringSecretData), signeringSecretData.count, [UInt8] (dataToSign), dataToSign.count, digestBytes) // base64 utdata la hmacData = Data (bytes: digestBytes, telle: digestLength) la signatur = hmacData.base64EncodedString () print ("HMAC signaturen i base64 er" + signatur) // eller HEX utgang la hexString = NSMutableString () for jeg i 0 ...  

I denne koden er CCHmac funksjonen tar en parameter for typen hash-funksjon som skal brukes sammen med to byte-strenger og deres lengder - meldingen og en hemmelig nøkkel. For å få best mulig sikkerhet, bruk minst en 256-biters (32 byte) nøkkel generert fra en kryptografisk sikker tilfeldig talgenerator. For å kontrollere at alt fungerer riktig på den andre siden, kjør eksemplet og skriv deretter inn den hemmelige nøkkelen og meldingen på denne eksterne serveren og kontroller at utgangen er den samme.

Du kan også legge til en tidsstempeloverskrift på forespørselen og signere streng for å gjøre forespørselen mer unik. Dette kan bidra til at API-utjevningen av replay-angrepene blir avsluttet. For eksempel kan API-en slette forespørselen hvis tidsstempel er 10 minutter gammel.

Selv om det er godt å holde fast ved å bruke SHA-versjoner som er sikre, viser det seg at mange av sikkerhetsproblemene til de usikre SHA-versjonene ikke gjelder for HMAC. Av denne grunn kan du se SHA1 som brukes i produksjonskode. Men fra et PR-synspunkt kan det se dårlig ut hvis du må forklare hvorfor, kryptografisk sett, det er greit å bruke SHA1 i denne sammenheng. Mange av svakhetene i SHA1 skyldes det som kalles kollisjon angrep. Kode revisorer eller sikkerhetsforskere kan forvente at koden din skal være kollisjonsbestandig, uavhengig av konteksten. Også, hvis du skriver modulær kode hvor du kan bytte ut signeringsfunksjonen til en annen i fremtiden, kan du glemme å oppdatere usikkerhetsfunksjonene. Derfor holder vi fremdeles til SHA-512 som vår valgfrie algoritme.

HMAC CPU-operasjonene er raske, men en ulempe er problemet med nøkkelutveksling. Hvordan lar vi hverandre vite hva den hemmelige nøkkelen er uten å bli fanget? For eksempel må API-en din dynamisk legge til eller fjerne flere apper eller plattformer fra en hvitliste. I dette scenariet vil apper være pålagt å registrere seg, og hemmeligheten må sendes til appen etter vellykket registrering. Du kan sende nøkkelen over HTTPS og bruke SSL pinning, men selv da er det alltid en bekymring at en eller annen måte nøkkelen blir stjålet under utvekslingen. Løsningen på problemet med nøkkelutveksling er å generere en nøkkel som ikke trenger å forlate enheten i utgangspunktet. Dette kan oppnås ved hjelp av Public Key Cryptography, og en veldig populær og akseptert standard er RSA.

RSA

RSA står for Rivest-Shamir-Adleman (forfatterne av kryptosystemet). Det innebærer å utnytte vanskeligheten ved å fakturere produktet av to meget store primtal. RSA kan brukes til kryptering eller autentisering, men for dette eksempelet skal vi bare bruke det for autentisering. RSA genererer to nøkler, en offentlig og en privat, som vi kan oppnå ved hjelp av SecKeyGeneratePair funksjon. Når den brukes til autentisering, brukes den private nøkkelen til å opprette signaturen, mens den offentlige nøkkelen verifiserer signaturen. Gitt en offentlig nøkkel, er det beregningsmessig unfeasible å utlede den private nøkkelen.

Det neste eksemplet viser hva Apple og alle de populære spillkonsollene bruker når de distribuerer programvaren. La oss si at firmaet ditt oppretter og leverer en fil med jevne mellomrom at brukerne vil dra inn i fildelingsdelen av appen din i iTunes. Du vil sørge for at filene du sender ut aldri blir manipulert før du blir analysert i appen. Din bedrift vil holde fast på og bevare den private nøkkelen som den bruker til å signere filene. I bunten av appen er en kopi av den offentlige nøkkelen som brukes til å verifisere filen. Gitt at privatnøkkelen aldri overføres eller inkluderes i appen, er det ikke mulig for en ondsinnet bruker å kunne signere egne versjoner av filene (bortsett fra å bryte inn i selskapet og stjele privatnøkkelen).

Vi vil bruke SecKeyRawSign å signere filen. Det ville være sakte å signere hele innholdet i filen ved hjelp av RSA, så hash av filen er signert i stedet. I tillegg bør dataene som sendes til RSA, også være hevet før signering på grunn av noen sikkerhetssvakheter.

@available (iOS 10.0, *) klasse FileSigner private var publicKey: SecKey? private var privateKey: SecKey? func generateKeys () -> String? var publicKeyString: String? // generere en ny keypair let parametere: [String: AnyObject] = [kSecAttrKeyType som streng: kSecAttrKeyTypeRSA, kSecAttrKeySizeInBits som streng: 4096 som AnyObject,] la status = SecKeyGeneratePair (parametere som CFDictionary, & publicKey, & privateKey) // --- Lagre nøkkelen din her // // Konverter SecKey-objektet til en representasjon som vi kan sende over nettverket hvis status == noErr && publicKey! = null hvis la cfData = SecKeyCopyExternalRepresentation (publicKey !, null) let data = cfData som Data publicKeyString = data.base64EncodedString () returner publicKeyString func signFile (_ path: String) -> String? var signatur: String? hvis la filData = FileManager.default.contents (atPath: path) if (privateKey! = null) // hash meldingen først la digestLength = Int (CC_SHA512_DIGEST_LENGTH) la hashBytes = UsikkertMutablePointer.tildele (kapasitet: digestLength) CC_SHA512 ([UInt8] (filData), CC_LONG (fileData.count), hashBytes) // logg let blockSize = SecKeyGetBlockSize (privateKey!) // i tilfelle av RSA er modulen det samme som blokken size var signatureBytes = [UInt8] (gjentatt: 0, telle: blockSize) var signatureDataLength = blockSize la status = SecKeyRawSign (privateKey !, .PKCS1SHA512, hashBytes, digestLength og signatureBytes, og signatureDataLength) hvis status == noErr la data = Data bytes: signaturBytes, count: signatureDataLength) signatur = data.base64EncodedString () retur signatur

I denne koden brukte vi CC_SHA512 funksjonen for å spesifisere SHA-512 igjen. (RSA, i motsetning til HMAC, blir usikker hvis den underliggende hashfunksjonen er usikker.) Vi bruker også 4096 som nøkkelstørrelse, som er satt av kSecAttrKeySizeInBits parameter. 2048 er den minste anbefalte størrelsen. Dette er for å forhindre et kraftig nettverk av datasystemer som spretter RSA-nøkkelen (ved å sprekke betyr jeg at RSA-nøkkelen er fakturert, også kjent som faktorisering av en offentlig modul). RSA-gruppen har anslått at 2048-bitnøkler kan bli sprekkbare noen gang før 2030. Hvis du vil at dataene dine skal være sikre utover den tiden, er det en god idé å velge en høyere nøkkelstørrelse som 4096.

De genererte nøklene er i form av SecKey objekter. Et problem med Apples implementering av SecKey er at den ikke inneholder all viktig informasjon som utgjør en offentlig nøkkel, så det er ikke et gyldig DER-kodet X.509-sertifikat. Hvis du legger til den manglende informasjonen tilbake i formatet for en iOS- eller OS X-app, krever selv server-sideplattformer som PHP, noe arbeid og innebærer å jobbe i et format kjent som ASN.1. Heldigvis ble dette løst i iOS 10 med nytt SecKey Funksjoner for å generere, eksportere og importere nøkler. 

Koden nedenfor viser deg den andre siden av kommunikasjonen - klassen som godtar en offentlig nøkkel via SecKeyCreateWithData å verifisere filer ved hjelp av SecKeyRawVerify funksjon.

@available (iOS 10.0, *) klasse FileVerifier private var publicKey: SecKey? func addPublicKey (_ keyString: String) -> Bool var suksess = false hvis la keyData = Data.init (base64Encoded: keyString) la parametere: [String: AnyObject] = [kSecAttrKeyType som streng: kSecAttrKeyTypeRSA, kSecAttrKeyClass som streng: kSecAttrKeyClassPublic , kSecAttrKeySizeInBits as String: 4096 som AnyObject, kSecReturnPersistentRef som streng: true as AnyObject] publicKey = SecKeyCreateWithData (keyData som CFData, parametere som CFDictionary, null) hvis (publicKey! = null) success = true returnere suksess func verifyFile _ bane: String, med Signatur signatur: String) -> Bool var suksess = feil hvis (publicKey! = null) hvis la filenData = FileManager.default.contents (atPath: bane) hvis la signatureData = Data.init (base64Encoded : signatur) // hash meldingen først la digestLength = Int (CC_SHA512_DIGEST_LENGTH) la hashBytes = UsikkertMutablePointer.allokere (kapasitet: digestLength) CC_SHA512 ([UInt8] (filData), CC_LONG (fileData.count), hashBytes) // bekreft la status = signatureData.withUnsafeBytes signaturBytes i retur SecKeyRawVerify (publicKey !, .PKCS1SHA512, hashBytes, digestLength, signatureBytes , signatureData.count) hvis status == noErr suksess = true else print ("Signature verifiseringsfeil") // - 9809: errSSLCrypto, etc returnere suksess

Du kan prøve dette ut og kontrollere at det fungerer ved hjelp av en enkel test som følgende:

hvis #available (iOS 10.0, *) guard la plistPath = Bundle.main.path (forResource: "Info", ofType: "plist") ellers print ("Kunne ikke få plist"); return la filenSigner = FileSigner () DispatchQueue.global (qos: .userInitiated) .async // RSA-nøkkelgen kan være langt løpende arbeid guard let publicKeyString = fileSigner.generateKeys () else print ("Nøkkelegenereringsfeil"); return // Tilbake til hovedtråden DispatchQueue.main.async guard la signature = fileSigner.signFile (plistPath) else print ("No signature"); return // Lag signaturen i den andre enden la filenVerifier = FileVerifier () guard fileVerifier.addPublicKey (publicKeyString) ellers print ("Nøkkel ble ikke lagt til"); return la suksess = fileVerifier.verifyFile (plistPath, medSignature: signatur) hvis suksess print ("Signatures match!") else print ("Signaturer stemmer ikke overens.") 

Det er en ulempe for RSA-nøkkelproduksjonen er sakte! Tiden for å generere nøklene er avhengig av størrelsen på nøkkelen. På nyere enheter tar en 4096 bitsnøkk bare noen få sekunder, men hvis du kjører denne koden på en iPod Touch 4. generasjon, kan det ta omtrent et minutt. Dette er greit hvis du bare lager nøklene noen ganger på en datamaskin, men hva skjer når vi trenger å generere nøkler ofte på en mobilenhet? Vi kan ikke bare senke nøkkelstørrelsen fordi det nedgraderer sikkerheten. 

Så hva er løsningen? Vel, elliptisk kurvekryptografi (ECC) er en up-and-coming tilnærming - et nytt sett med algoritmer basert på elliptiske kurver over endige felt. ECC-nøkler er mye mindre i størrelse og raskere å generere enn RSA-nøkler. En nøkkel på bare 256 bits gir et veldig sterkt nivå på sikkerhet! For å dra nytte av ECC trenger vi ikke å endre mye kode. Vi kan signere våre data ved hjelp av det samme SecKeyRawSign funksjon og deretter justere parametrene for å bruke Elliptic Curve Digital Signature Algorithm (ECDSA).

Tips: For flere RSA-implementeringsideer kan du sjekke ut SwiftyRSA hjelpebibliotek, som er fokusert på kryptering og signering av meldinger.

ECDSA

Tenk på følgende scenario: En chat app lar brukerne sende private meldinger til hverandre, men du vil forsikre deg om at en motstander ikke har endret meldingen på vei til den andre brukeren. La oss se hvordan du kan sikre kommunikasjonen med kryptografi. 

For det første genererer hver bruker et tastatur av offentlige og private nøkler på mobilenheten. Deres private nøkler lagres i minnet, og aldri forlate enheten, mens de offentlige nøklene overføres til hverandre. Som tidligere brukes den private nøkkelen til å signere dataene som sendes ut, mens den offentlige nøkkelen brukes til å verifisere. Hvis en angriper skulle fange en offentlig nøkkel under transitt, var alt som kunne gjøres, å verifisere integriteten til den opprinnelige meldingen fra avsenderen. En angriper kan ikke endre en melding fordi de ikke har den private nøkkelen som trengs for å rekonstruere signaturen.

Det er en annen pro til å bruke ECDSA på iOS. Vi kan gjøre bruk av det faktum at elliptiske kurve nøkler er de eneste som for øyeblikket kan lagres i den sikre enklaven til enheten. Alle andre nøkler lagres i nøkkelringen som krypterer elementene til standard lagringsområdet på enheten. På enheter som har en, er den sikre enklaven skilt fra prosessoren, og nøkkeloppbevaring er implementert i maskinvare uten direkte programvaretilgang. Den sikre enklaven kan lagre en privat nøkkel og operere på den for å produsere utdata som sendes til appen din uten å utsette den faktiske private nøkkelen ved å laste den inn i minnet!

Jeg vil legge til støtte for å opprette ECDSA private nøkkel på den sikre enklaven ved å legge til kSecAttrTokenIDSecureEnclave alternativ for kSecAttrTokenID parameter. Vi kan starte dette eksemplet med en Bruker objekt som vil generere et keypair ved initialisering.

@available (iOS 9.0, *) klasse Bruker public var publicKey: SecKey? private var privateKey: SecKey? privat var mottaker: Bruker? init (withUserID id: String) // hvis la access = SecAccessControlCreateWithFlags (nil, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, [.privateKeyUsage / *, .userPresence] autentisering brukergrensesnitt for å få den private nøkkelen * /], null) // Force store kun hvis passord eller Trykk på ID-oppsett ... hvis la tilgang = SecAccessControlCreateWithFlags (null, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, [.privateKeyUsage], null) // Hold privat nøkkel på enheten let privateTagString = "com.example.privateKey." + id la privateTag = privateTagString.data (bruk: .utf8)! // Lagre det som data, ikke som en streng, la privateKeyParameters: [String: AnyObject] = [kSecAttrIsPermanent as String: true as AnyObject, kSecAttrAccessControl as String: få tilgang som AnyObject, kSecAttrApplicationTag som streng: privatTag som AnyObject,] la publicTagString = " com.example.publicKey." + id la publicTag = publicTagString.data (bruk: .utf8)! // Data, ikke String la publicKeyParameters: [String: AnyObject] = [kSecAttrIsPermanent as String: false som AnyObject, kSecAttrApplicationTag som streng: publicTag as AnyObject,] la keyPairParameters: [String: AnyObject] = [kSecAttrKeySizeInBits as String: 256 som AnyObject , kSecAttrKeyType som String: kSecAttrKeyTypeEC, kSecPrivateKeyAttrs som String: privateKeyParameters som AnyObject, kSecAttrTokenID som String: kSecAttrTokenIDSecureEnclave som AnyObject, // Lagres Secure Enclave kSecPublicKeyAttrs som String: publicKeyParameters som AnyObject] la status = SecKeyGeneratePair (keyPairParameters som CFDictionary, og publicKey & Privat) hvis status! = noErr print ("Nøkkelegenereringsfeil") // ... 

Deretter skal vi opprette noen hjelper- og eksempelfunksjoner. For eksempel vil klassen tillate en bruker å starte en samtale og sende en melding. Selvfølgelig, i appen din, ville du konfigurere dette for å inkludere ditt bestemte nettverksoppsett.

 // ... privat func sha512Digest (forData data: Data) -> Data let len ​​= Int (CC_SHA512_DIGEST_LENGTH) la digest = UsikkerMutabelPointer.allokere (kapasitet: len) CC_SHA512 ((data som NSData) .bytes, CC_LONG (data.count), fordøye) returnere NSData (bytesNoCopy: UnsafeMutableRawPointer (fordøye), lengde: len) som Data public func initateConversation (withUser user: User ) -> Bool var suksess = false hvis publicKey! = Null user.receiveInitialization (self) recipient = user success = true returnere suksess public func receiveInitialization (_ user: User) recipient = user public func sendMessage melding: String) hvis la data = message.data (bruk: .utf8) la signatur = self.signData (plainText: data) hvis signatur! = nil self.recipient? .receiveMessage (melding, med Signatur: signatur!)  offentlige func receiveMessage (_ melding: String, med SignaturMatch = Data) la signatureMatch = verifiser SignaturMatch = verifiseringSignatur (bruk: .utf8) !, signatur: signatur) hvis signaturMatch print ("Mottatt melding. bekreftet. Melding er: ", melding) else print (" Mottatt melding. Signaturfeil. ") // ... 

Deretter skal vi gjøre selve signeringen og verifiseringen. ECDSA, i motsetning til RSA, trenger ikke å være hashed før signering. Men hvis du vil ha en funksjon der algoritmen enkelt kan byttes uten å gjøre mange endringer, er det helt greit å fortsette å hash dataene før du signerer.

 // ... func signData (plainText: Data) -> Data? guard privateKey! = nil else print ("Privat nøkkel utilgjengelig") returner null la digestToSign = self.sha512Digest (forData: plainText) la signatur = UsikkerMutabelPointer.allokere (kapasitet: 512) // 512 - overhead var signaturLength = 512 la status = SecKeyRawSign (privateKey !, .PKCS1SHA512, [UInt8] (digestToSign), Int (CC_SHA512_DIGEST_LENGTH), signatur og signaturlengde) hvis status! = noErr print "Signatur mislykkes: \ (status)" Return Data.init (bytes: signatur, count: signatureLength) // endre størrelse til faktisk signaturstørrelse func verifySignature (plainText: Data, signatur: Data) -> Bool vaktmottaker? .publicKey! = nil else print ("Mottaker offentlig nøkkel utilgjengelig") returner falskt la digestToVerify = self.sha512Digest (forData: plainText) la signedHashBytesSize = signature.count la status = SecKeyRawVerify (mottaker! .publicKey !, .PKCS1SHA512, [UInt8] (digestToVerify), Int (CC_SHA512_DIGEST_LENGTH), [UInt8] (signatur som Data), signertHashBytesSize) returneringsstatus == noErr

Dette bekrefter meldingen, så vel som "identifiser" av en bestemt bruker siden bare den brukeren har besittelse av sin private nøkkel. 

Dette betyr ikke at vi knytter nøkkelen til hvem brukeren er i virkeligheten. Problemet med å matche en offentlig nøkkel til en bestemt bruker er et annet domene. Mens løsningene ikke er omfattet av denne opplæringen, tillater populære sikre chat-apper som Signal og Telegram brukere å verifisere et fingeravtrykk eller nummer via en sekundær kommunikasjonskanal. På samme måte tilbyr Pidgin et spørsmål og svar system hvor du stiller et spørsmål som bare brukeren burde vite. Disse løsningene åpner en hel verden av debatt om hva den beste tilnærmingen skal være.

Men vår kryptografiske løsning bekrefter at meldingen kun kan sendes av noen som har en bestemt privat nøkkel.

La oss utføre en enkel test av vårt eksempel:

hvis #available (iOS 9.0, *) la alice = User.init (withUserID: "aaaaaa1") la bob = User.init (withUserID: "aaaaaa2") akseptert = alice.initiateConversation (withUser: bob) if ) alice.sendMessage ("Hei der") bob.sendMessage ("Test melding") alice.sendMessage ("En annen testmelding")

OAuth og SSO

Ofte når du arbeider med tredjepartstjenester, vil du legge merke til andre høytstående vilkår som brukes til godkjenning, for eksempel OAuth og SSO. Mens denne opplæringen handler om å skape en signatur, vil jeg kort forklare hva de andre vilkårene betyr.

OAuth er en protokoll for godkjenning og autorisasjon. Det fungerer som mellommann til å bruke en persons konto for tredjepartstjenester og har som mål å løse problemet med å selektivt godkjenne tilgang til dataene dine. Hvis du logger deg på for å betjene X via Facebook, spør en skjerm deg, for eksempel om tjenesten X har lov til å få tilgang til dine Facebook-bilder. Den oppnår dette ved å gi et token uten å avsløre brukerens passord.

Enkelt pålogging, eller SSO, beskriver strømmen der en autentisert bruker kan bruke samme innloggingsinformasjon for å få tilgang til flere tjenester. Et eksempel på dette er hvordan Gmail-kontoen din fungerer for å logge på YouTube. Hvis du hadde flere forskjellige tjenester hos firmaet ditt, kan du ikke opprette separate brukerkontoer for alle de forskjellige tjenestene.

Konklusjon

I denne veiledningen så du hvordan du lager signaturer med de mest populære standardene. Nå som vi har dekket alle hovedkonseptene, la oss gjenskape!

  • Bruk HMAC når du trenger fart og er sikker på at den hemmelige nøkkelen kan byttes sikkert.
  • Hvis tastene må reise over et nettverk, er det bedre å bruke RSA eller ECDSA.
  • RSA er fortsatt den mest populære standarden. Bekreftelsestrinnet er ganske fort. Bruk RSA hvis resten av teamet ditt allerede er kjent med eller bruker standarden.
  • Hvis du fortsatt trenger å generere nøkler på en treg enhet, bruker du ECDSA. Mens ECDSA-verifikasjonen er litt tregere enn RSA-verifisering, sammenlignes det ikke med de mange sekunder lagret over RSA for nøkkelgenerering.

Så det er det for digitale signaturer i Swift. Hvis du har noen spørsmål, vær så snill å slippe meg en linje i kommentarfeltet, og i mellomtiden sjekke ut noen av våre andre veiledninger om datasikkerhet og apputvikling i Swift!