---
title: "Kryptografisk signering"
version: 5.2
locale: sv
source: https://docs.djangoproject.com/sv/5.2/topics/signing/
canonical: https://djangodocs.dev/sv/5.2/topics/signing/
---
# Kryptografisk signering

Den gyllene regeln för säkerhet i webbapplikationer är att aldrig lita på data från källor som inte är betrodda. Ibland kan det vara användbart att skicka data genom ett icke betrott medium. Kryptografiskt signerade värden kan skickas genom en icke betrodd kanal i trygg förvissning om att eventuell manipulering kommer att upptäckas.

Django tillhandahåller både ett API på låg nivå för att signera värden och ett API på hög nivå för att ställa in och läsa signerade cookies, en av de vanligaste användningarna av signering i webbapplikationer.

Du kanske också tycker att det är bra att skriva under för följande:

- Generering av URL:er för ”återställ mitt konto” som skickas till användare som har förlorat sitt lösenord.
- Säkerställa att data som lagras i dolda formulärfält inte har manipulerats.
- Generera hemliga URL:er för engångsbruk för att ge tillfällig tillgång till en skyddad resurs, t.ex. en nedladdningsbar fil som en användare har betalat för.

## Skydda `SECRET_KEY` och `SECRET_KEY_FALLBACKS`

När du skapar ett nytt Django-projekt med [`startproject`](/sv/5.2/ref/django-admin/#django-admin-startproject), genereras filen `settings.py` automatiskt och får ett slumpmässigt [`SECRET_KEY`](/sv/5.2/ref/settings/#std-setting-SECRET_KEY)-värde. Detta värde är nyckeln till att säkra signerade data - det är viktigt att du håller det säkert, annars kan angripare använda det för att generera sina egna signerade värden.

[`SECRET_KEY_FALLBACKS`](/sv/5.2/ref/settings/#std-setting-SECRET_KEY_FALLBACKS) kan användas för att rotera hemliga nycklar. Värdena kommer inte att användas för att signera data, men om de anges kommer de att användas för att validera signerade data och måste hållas säkra.

## Använda API:et på låg nivå

Djangos signeringsmetoder finns i modulen `django.core.signing`. För att signera ett värde, instansiera först en `Signer` instans:

```pycon
>>> from django.core.signing import Signer
>>> signer = Signer()
>>> value = signer.sign("My string")
>>> value
'My string:v9G-nxfz3iQGTXrePqYPlGvH79WTcIgj1QIQSUODTW0'
```

Signaturen läggs till i slutet av strängen, efter kolon. Du kan hämta originalvärdet med hjälp av metoden `unsign`:

```pycon
>>> original = signer.unsign(value)
>>> original
'My string'
```

Om du skickar ett värde som inte är en sträng till `sign`, kommer värdet att tvingas till sträng innan det signeras, och `unsign`-resultatet kommer att ge dig strängvärdet:

```pycon
>>> signed = signer.sign(2.5)
>>> original = signer.unsign(signed)
>>> original
'2.5'
```

Om du vill skydda en lista, tupel eller dictionary kan du göra det med hjälp av metoderna `sign_object()` och `unsign_object()`:

```pycon
>>> signed_obj = signer.sign_object({"message": "Hello!"})
>>> signed_obj
'eyJtZXNzYWdlIjoiSGVsbG8hIn0:bzb48DBkB-bwLaCnUVB75r5VAPUEpzWJPrTb80JMIXM'
>>> obj = signer.unsign_object(signed_obj)
>>> obj
{'message': 'Hello!'}
```

Se [Skydd av komplexa datastrukturer](#signing-complex-data) för mer information.

Om signaturen eller värdet har ändrats på något sätt, kommer ett `django.core.signing.BadSignature` undantag att uppstå:

```pycon
>>> from django.core import signing
>>> value += "m"
>>> try:
...     original = signer.unsign(value)
... except signing.BadSignature:
...     print("Tampering detected!")
...
```

Som standard använder klassen `Signer` inställningen [`SECRET_KEY`](/sv/5.2/ref/settings/#std-setting-SECRET_KEY) för att generera signaturer. Du kan använda en annan hemlighet genom att skicka den till konstruktören för `Signer`:

```pycon
>>> signer = Signer(key="my-other-secret")
>>> value = signer.sign("My string")
>>> value
'My string:o3DrrsT6JRB73t-HDymfDNbTSxfMlom2d8TiUlb1hWY'
```

#### `class Signer(* (Keyword-only parameters separator (PEP 3102)), key=None, sep=':', salt=None, algorithm=None, fallback_keys=None)`

Returnerar en signerare som använder `key` för att generera signaturer och `sep` för att separera värden. `sep` kan inte vara i [**URL safe base64 alphabet**](https://datatracker.ietf.org/doc/html/rfc4648.html#section-5). Detta alfabet innehåller alfanumeriska tecken, bindestreck och understrykningstecken. `algoritm` måste vara en algoritm som stöds av [`hashlib`](https://docs.python.org/3/library/hashlib.html#module-hashlib), standard är `'sha256'`. `fallback_keys` är en lista med ytterligare värden som används för att validera signerade data, standard är [`SECRET_KEY_FALLBACKS`](/sv/5.2/ref/settings/#std-setting-SECRET_KEY_FALLBACKS).

### Använda argumentet `salt`

Om du inte vill att alla förekomster av en viss sträng ska ha samma signaturhash kan du använda det valfria argumentet `salt` till klassen `Signer`. Om du använder ett salt kommer den signerande hashfunktionen att seedas med både saltet och din [`SECRET_KEY`](/sv/5.2/ref/settings/#std-setting-SECRET_KEY):

```pycon
>>> signer = Signer()
>>> signer.sign("My string")
'My string:v9G-nxfz3iQGTXrePqYPlGvH79WTcIgj1QIQSUODTW0'
>>> signer.sign_object({"message": "Hello!"})
'eyJtZXNzYWdlIjoiSGVsbG8hIn0:bzb48DBkB-bwLaCnUVB75r5VAPUEpzWJPrTb80JMIXM'
>>> signer = Signer(salt="extra")
>>> signer.sign("My string")
'My string:YMD-FR6rof3heDkFRffdmG4pXbAZSOtb-aQxg3vmmfc'
>>> signer.unsign("My string:YMD-FR6rof3heDkFRffdmG4pXbAZSOtb-aQxg3vmmfc")
'My string'
>>> signer.sign_object({"message": "Hello!"})
'eyJtZXNzYWdlIjoiSGVsbG8hIn0:-UWSLCE-oUAHzhkHviYz3SOZYBjFKllEOyVZNuUtM-I'
>>> signer.unsign_object(
...     "eyJtZXNzYWdlIjoiSGVsbG8hIn0:-UWSLCE-oUAHzhkHviYz3SOZYBjFKllEOyVZNuUtM-I"
... )
{'message': 'Hello!'}
```

Genom att använda salt på det här sättet hamnar de olika signaturerna i olika namnrymder.  En signatur som kommer från en namnrymd (ett visst saltvärde) kan inte användas för att validera samma klartextsträng i en annan namnrymd som använder en annan saltinställning. Resultatet är att en angripare inte kan använda en signerad sträng som genererats på ett ställe i koden som indata till en annan koddel som genererar (och verifierar) signaturer med ett annat salt.

Till skillnad från din [`SECRET_KEY`](/sv/5.2/ref/settings/#std-setting-SECRET_KEY) behöver ditt saltargument inte vara hemligt.

### Verifiering av tidsstämplade värden

`TimestampSigner` är en subklass av [`Signer`](#django.core.signing.Signer) som lägger till en signerad tidsstämpel till värdet. Detta gör att du kan bekräfta att ett signerat värde skapades inom en viss tidsperiod:

```pycon
>>> from datetime import timedelta
>>> from django.core.signing import TimestampSigner
>>> signer = TimestampSigner()
>>> value = signer.sign("hello")
>>> value
'hello:1stLqR:_rvr4oXCgT4HyfwjXaU39QvTnuNuUthFRCzNOy4Hqt0'
>>> signer.unsign(value)
'hello'
>>> signer.unsign(value, max_age=10)
SignatureExpired: Signature age 15.5289158821 > 10 seconds
>>> signer.unsign(value, max_age=20)
'hello'
>>> signer.unsign(value, max_age=timedelta(seconds=20))
'hello'
```

#### `class TimestampSigner(* (Keyword-only parameters separator (PEP 3102)), key=None, sep=':', salt=None, algorithm='sha256')`

#### `sign(value)`

Skriv `värde` och lägg till aktuell tidsstämpel till det.

#### `unsign(value, max_age=None)`

Kontrollerar om `värde` signerades för mindre än `max_age` sekunder sedan, annars utlöses `SignatureExpired`. Parametern `max_age` kan acceptera ett heltal eller ett [`datetime.timedelta`](https://docs.python.org/3/library/datetime.html#datetime.timedelta)-objekt.

#### `sign_object(obj, serializer=JSONSerializer, compress=False)`

Koda, eventuellt komprimera, lägga till aktuell tidsstämpel och signera komplex datastruktur (t.ex. lista, tupel eller ordbok).

#### `unsign_object(signed_obj, serializer=JSONSerializer, max_age=None)`

Kontrollerar om `signed_obj` signerades för mindre än `max_age` sekunder sedan, annars uppstår `SignatureExpired`. Parametern `max_age` kan acceptera ett heltal eller ett [`datetime.timedelta`](https://docs.python.org/3/library/datetime.html#datetime.timedelta)-objekt.

### Skydd av komplexa datastrukturer

Om du vill skydda en lista, tupel eller dictionary kan du göra det med hjälp av metoderna `Signer.sign_object()` och `unsign_object()`, eller signeringsmodulens `dumps()` eller `loads()` funktioner (som är förkortningar för `TimestampSigner(salt='django.core.signing').sign_object()/unsign_object()`). Dessa använder JSON-serialisering under huven. JSON säkerställer att även om din [`SECRET_KEY`](/sv/5.2/ref/settings/#std-setting-SECRET_KEY) blir stulen kommer en angripare inte att kunna utföra godtyckliga kommandon genom att utnyttja pickle-formatet:

```pycon
>>> from django.core import signing
>>> signer = signing.TimestampSigner()
>>> value = signer.sign_object({"foo": "bar"})
>>> value
'eyJmb28iOiJiYXIifQ:1stLrZ:_QiOBHafwucBF9FyAr54qEs84ZO1UdsO1XiTJCvvdno'
>>> signer.unsign_object(value)
{'foo': 'bar'}
>>> value = signing.dumps({"foo": "bar"})
>>> value
'eyJmb28iOiJiYXIifQ:1stLsC:JItq2ZVjmAK6ivrWI-v1Gk1QVf2hOF52oaEqhZHca7I'
>>> signing.loads(value)
{'foo': 'bar'}
```

På grund av JSON:s natur (det finns ingen inbyggd skillnad mellan listor och tupler) kommer du att få en lista från `signing.loads(object)` om du skickar in en tupel:

```pycon
>>> from django.core import signing
>>> value = signing.dumps(("a", "b", "c"))
>>> signing.loads(value)
['a', 'b', 'c']
```

#### `dumps(obj, key=None, salt='django.core.signing', serializer=JSONSerializer, compress=False)`

Returnerar URL-säker, signerad base64-komprimerad JSON-sträng. Det serialiserade objektet signeras med hjälp av [`TimestampSigner`](#django.core.signing.TimestampSigner).

#### `loads(string, key=None, salt='django.core.signing', serializer=JSONSerializer, max_age=None, fallback_keys=None)`

Motsatsen till `dumps()`, ger `BadSignature` om signaturen misslyckas. Kontrollerar `max_age` (i sekunder) om den är angiven.
