Diskkryptering i linux debian. LUKS, EncFS och CryptoFS datakrypteringssystem för Linux

Diskkryptering i linux debian.  LUKS, EncFS och CryptoFS datakrypteringssystem för Linux
Diskkryptering i linux debian. LUKS, EncFS och CryptoFS datakrypteringssystem för Linux

I den här artikeln kommer jag att berätta hur du skapar en dold kryptobehållare. standardmedel Linux OS (LUKS och cryptsetup). Inbyggda funktioner i LUKS (som att använda externa rubriker och placera verklig data vid en given offset) tillåter användaren att komma åt data gömd inuti en befintlig container, samt förneka existensen av sådan data.

UPD: Eftersom det här inlägget var klart för en månad sedan kunde jag inte ens föreställa mig en så märklig och oväntad död av projektet. Nåväl, ja, den kanske inte har dött helt än, låt oss se... Ändå, i den här texten, bestämde jag mig för att lämna alla referenser till TrueCrypt som de är.

Vad är "plausibel förnekelse"?

Du kan hitta en mycket lång och detaljerad beskrivning av detta koncept på Wikipedia: http://en.wikipedia.org/wiki/Plausible_deniability . I korthet betyder det att du kan ha något (eller kunde ha gjort något), vars närvaro inte kan misstänkas eller bevisas av någon (om du inte erkänner det själv förstås). Och efteråt kan du förneka existensen (eller faktumet att göra) detta, om någon vill anklaga dig, eftersom (jag upprepar) detta faktum är obevisbart. Tja, till exempel, om ett barn sparkade sin lillebror i rumpan, och brodern gick för att söka rättvisa från sina föräldrar, vad skulle hända i det här fallet?

Tja... Som om ingenting händer. Eftersom den här snubben kommer att vägra, och föräldrarna formellt sett kommer inte att kunna fånga honom i handen (eftersom det för det första inte finns några vittnen, och för det andra kan den yngre brodern spela sitt smutsiga spel). Ingen kommer alltså att straffas. Tja, annars kommer de att straffa båda för varje brandman. Detta var bara ett exempel på användningen av möjligheten till rimlig förnekelse av ett barn som är utsatt för aggression. Men du och jag är naturligtvis vita och fluffiga, och vi kommer att använda dolda behållare enbart för att skydda våra personuppgifter från skurkar. Så rätt? Naturligtvis är "vad som är "bra" och vad som är "dåligt"" en separat fråga ... Men mer till saken.

Allmän idé om implementering

Anta att vi vill lagra några viktiga data i en krypterad fil. I allmänhet kommer vi att använda något slags kryptoskyddsprogram som kommer att göra allt det smutsiga arbetet åt oss. Vi kanske vill behandla den krypterade filen som om den vore en virtuell disk, och detta minskar antalet potentiella kandidater avsevärt. Det finns dock ett "men". Nästan alla sådana program fungerar med en fil som med en bit krypterad data. Låt mig förklara: brukaren har vanligtvis ett lösenord (och kanske några "reserv") för Allt data inuti behållaren. Det betyder att det finns minst en svag länk: containerlösenordet. Jag vill inte nämna att lösenordet måste vara kryptografiskt starkt, för det är en vanlig sanning. Vad jag menar är att om användaren ger upp lösenordet av någon anledning (t.ex. under tvång), kommer all data att läsas. Och detta faktum verkar sorgligt och helt fel för mig ...

Men det finns i allmänhet hopp. :) Det finns till exempel ett program som , vilket är ganska smart. Användaren kan skapa två behållare i en fil: en är en "dummy" med ett visst antal "förbjudna", men relativt säkra filer, och den andra är en riktig, med data som inte bör exponeras under några omständigheter. Således ber TrueCrypt om två olika lösenord när en användare vill skapa en sådan "dubbel" behållare. Under drift anger användaren endast ett lösenord för den "riktiga" delen och arbetar med det. I händelse av att användaren, under påtryckningar från yttre omständigheter, tvingas avslöja innehållet i behållaren till tredje part, anger han helt enkelt ett annat lösenord, och TrueCrypt öppnar "falsk". Jag betonar (och detta är verkligen viktigt) att det inte finns något sätt att bevisa närvaron av den dolda delen om forskaren inte känner till motsvarande lösenord.

Och låt oss nu snabbt ta reda på hur detta skräp fungerar ... Faktum är att allt är väldigt enkelt. Programvaran delar upp containerfilen i två (i allmänhet ojämlika) delar. Den första delen, som kan vara relativt liten, innehåller speciellt framställda data; den andra är verklig. Följaktligen måste programmet kunna arbeta med två olika headers (konfigurationer) för två olika delar, samt kunna välja vilken del som ska dekrypteras beroende på lösenordet som användaren angett. Och detta, måste jag säga, är inte den mest triviala delen av arbetet. Tja, helt enkelt för att "officiellt" bara en "falsk" konfiguration borde vara synlig: om behållaren har en standardhuvud bör den bara vara en "falsk" rubrik; om behållarparametrarna är lagrade i en separat konfiguration bör denna konfiguration tillåta dekryptering av endast den "falska" delen. Och efter att ha dechiffrerat den "falska" delen borde det inte finnas en enda antydan om närvaron av den riktiga. De måste vara helt oberoende. Dessutom, när den "falska" delen öppnas, bör programvaran visa hela kapaciteten för kryptobehållaren, även om volymen av denna del är mycket mindre.

Så hur är det med LUKS?

Tja, här har vi goda nyheter och... ehm... ännu fler goda nyheter.

Den goda nyheten är att cryptsetup kan dekryptera och montera volymer skapade av TrueCrypt ". Läs endast, men detta är nonsens. Eftersom det finns bättre nyheter. Vi kan nämligen skapa "dolda" behållare enbart med hjälp av . Dessutom låter detta verktyg dig skapa valfritt antal "dolda" delar. Naturligtvis inom rimliga gränser. Och här är hur det kan göras.

Men innan du fortsätter,

ENORMT FETT LÄSKIG VARNING!!!

  • Allt som beskrivs nedan kan orsaka oåterkallelig dataförlust.
  • I ditt land kan användningen av stark kryptografi vara förbjuden, så du kan bli fängslad inte för riktig information, utan bara för att ha en kryptobehållare som kommer att hittas på din skruv.
  • Kryptografi kan skydda dina data, men det skyddar dig inte från tortyr. En dold behållare kan hjälpa till att behålla värdefull information, men du kan inte förneka dess närvaro i händelse av svek eller uppsägning.
  • Killarna som är intresserade av din krypterade data kanske inte är så dumma som du förväntade dig. Även om de inte kan bevisa närvaron av en dold del av behållaren kan de mycket väl låsa in dig i samma cell med rutinerade brottslingar, och om ett par dagar kommer du ihåg alla lösenord för all dold data.
  • Om du har nära människor (flickvän/pojkvän, släktingar, vänner) kan de lika gärna bli ett mål för hård press. Och detta kommer säkert att hjälpa dig att komma ihåg allt i allmänhet mycket snabbare, inklusive det du inte ens visste.

Så det är bättre att tänka två gånger på hur mycket information som är mer värdefull än ditt liv och dina nära och kära. Och gör en backup. För säkerhets skull.

Tja, man cryptsetup kan berätta många intressanta detaljer om kommandoradsparametrarna för detta verktyg. Tja, låt oss till exempel titta på --header-alternativet:

Okej. Det betyder att vi nu kan ha en datamängd fylld med slumpmässigt skräp, helt utan meningsfulla signaturer. Beskrivningen av detta alternativ innehåller lite mer information, varningar och varningar, men på den nedersta raden är detta allt som krävs. Jag rekommenderar dock starkt att läsa denna utmärkta guide.

Ett annat mycket användbart alternativ är --align-payload , som låter dig placera den verkliga datan vid en viss offset i förhållande till början av volymen:

Och detta är också coolt, för nu kan vi fritt flytta vår data till vilken del av volymen som helst. Du fattar, eller hur?

  1. Vi initierar volymen för kryptering: vi skriver över den helt med slumpmässiga data.
  2. Vi gör en "officiell" krypterad volym och släpper lite infekterad varese, coiled muzla, pron användbar gratis programvara, inspelningar från ditt amatörrockband, kärleksfilmer, etc. i allmänhet, för vilka du inte får mer än två års prövotid.
  3. Med hjälp av ovanstående esoteriska krypteringsalternativ skapar vi en dold volym (inuti den "officiella") och överför dess titel till externa media. Här kan du lagra riktigt farlig information (som dina dagisfoton eller planer på att erövra världen).

Egentligen, gott folk, det är allt. Ingen magi. Naturligtvis kan du inte fylla på den "officiella" krypterade disken av den enkla anledningen att en del av dess utrymme överlåts till en dold behållare. Och, som jag sa i början, kan du, om du vill, skapa flera dolda enheter enligt samma logik.

Här ... Och om du fortfarande behöver detaljer, då speciellt för dig -

Genomgång

Uppmärksamhet!

Följande kommandon kommer att förstöra din data om de körs utan att slå på hjärnan. Förlorad information kan inte återställas eftersom verktyg som dd fungerar på en låg nivå (det vill säga under filsystemsnivån). Därför kommer det inte att vara möjligt att återställa ändringar eller ångra deras effekt, även om du avbryter direkt efter lanseringen.

Kort sagt, gör inte detta om du inte kan komma på en meningsfull förklaring till hur varje steg relaterar till dina mål. Och gör en backup. Nu.

Så låt oss säga att vi har en enhet med flera partitioner. Låt det till exempel vara /dev/sdb. Och låt /dev/sdb1 vara en relativt liten (8GB) partition dedikerad till kryptering. Vi kommer att dela den 5 till 3, där 5 GB-delen kommer att vara "officiell" och 3 GB-delen kommer att döljas. Låt oss också anta att vi kommer att behålla nyckeln för den krypterade disken i /etc/keys, respektive rubriken för den dolda behållaren, på en extern USB-enhet, som vi monterar i /media/user/ExtUSBStick. Jag antar att du redan vet vilka behörigheter du behöver ställa in på nyckellagret, hur man konfigurerar encfs / ecryptfs för att säkert lagra konfidentiell data på osäkra enheter, och att det är vettigt att kopiera riktiga hemliga nycklar och lagra dem i flera geografiskt åtskilda kassaskåp.

Nåväl, okej, jag knorrar och går vidare till problemets kärna.

    Enhetsinitiering /dev/sdb1:

    Dd om=/dev/urandom av=/dev/sdb1 bs=16M

    Vi gör en nyckel för en krypterad volym. 512 bitar (64 byte) för våra ändamål genom taket:

    Dd if=/dev/urandom bs=64 count=1 >/etc/keys/secret.key 2>/dev/null

    Kryptera volymen med den nyskapade nyckeln:

    Cryptsetup luksFormat /dev/sdb1 /etc/keys/secret.key

    Öppna den krypterade enheten och konfigurera mappningen i hemliga data:

    Cryptsetup luksOpen --key-file /etc/keys/secret.key \ /dev/sdb1 secretdata

    Skapa på en krypterad volym filsystem(t.ex. btrfs):

    Mkfs.btrfs -L SecretData /dev/mapper/secretdata

    ... och montera den:

    Montera /dev/mapper/secretdata /var/secretdata/

    Med tanke på gränsen på 5 gig, ställ in subvolymkvoten:

    Btrfs kvot aktivera /var/secretdata/

    Eftersom btrfs-kvoter endast gäller för undervolymer, låt oss skapa en sådan sak:

    brfs undervolym skapa /var/secretdata/workingvolume

    ... och tillämpa den angivna kvoten på den (observera att btrfs-undervolymer kan monteras som vanliga filsystem, så det kan vara bekvämare för dig att montera just den här undervolymen istället för hela fs senare):

    btrfs qgroup limit 5G /var/secretdata/workingvolume

    Vi fyller den med några uppgifter:

    debootstrap --variant=buildd testning /var/secretdata/workingvolume

    Det är allt, nu kan du glömma den här delen:

    Umount /var/secretdata cryptsetup luksStäng hemliga data

    Låt oss nu skapa en "fisk" för rubriken och stoppa in slumpmässigt skräp i den:

    Dd if=/dev/urandom of=/media/user/ExtUSBStick/hidden.head bs=4M count=1

    Och nu kommer själva ögonblicket då den verkliga magin börjar. (Vad? Sa jag att det inte fanns någon magi? Så jag ljög.) Vi använder samma hemliga nyckel, dock inte i sin helhet, utan bara hälften (från en offset på 32 byte). De återstående 256 slumpmässiga bitarna är dock ganska kapabla att göra en bra nyckel. Sedan kommer vi att separera rubriken och lägga den på flashenheten. Slutligen säger vi till cryptsetup "y" att vi vill kompensera vår dolda behållare med 5 GB (dvs. 10485760 512-byte block) från början av volymen:

    Cryptsetup --keyfile-offset 32 ​​​​-header /media/user/ExtUSBStick/hidden.head \ --align-payload 10485760 luksFormat /dev/sdb1 /etc/keys/secret.key

    Ja, så enkelt är det. Låt oss nu öppna en ny krypterad enhet:

    Cryptsetup luksOpen --key-file /etc/keys/secret.key --keyfile-offset 32 ​​​​\ --header /media/user/ExtUSBStick/hidden.head /dev/sdb1 realsecretdata

    Låt oss rulla vilka fs vi vill ha:

    Mkfs.btrfs /dev/mapper/realsecretdata

Användbara länkar

För den som vill veta lite mer kommer här några ytterligare källor information:

  • diskkryptering, allmän information om diskkryptering: https://wiki.archlinux.org/index.php/Disk_encryption
  • Nekad kryptering, är begreppet något snävare än "plausibel förnekelse", som endast hänvisar till kryptografiområdet: https://en.wikipedia.org/wiki/Deniable_encryption
  • TrueCrypt

I den här artikeln ska jag försöka jämföra prestanda för olika krypteringssystem under linux. I teorin är det naturligtvis känt vilket system som är mer produktivt, och försöker beräkna prestandan olika system var (). Truecrypt innehåller till och med ett inbyggt riktmärke (som dock visar prestandan på RAM, den kan bara användas för att utvärdera hastigheten på olika krypteringsalgoritmer). Jag kommer att göra något annorlunda - jag kommer att mäta hastigheten på ett filsystem som krypterats på olika sätt i procent jämfört med ett konventionellt okrypterat filsystem.


Vi kommer att kryptera en separat partition på en separat hårddisk som inte innehåller ett rotfilsystem med den algoritm som används som standard i varje specifikt fall. Hur vanlig användare, jag förstår inte nyanserna i krypteringsstandarder (till exempel hur RIPEMD-160 hashing skiljer sig från Whirpool, vilket av dessa lägen är snabbare, vilket ger högre skydd), så vi litar bara på det faktum att tillverkarna av varje mjukvaruprodukt valde tillräckligt kryptoresistenta standardparametrar. Kanske är detta inte helt korrekt, eftersom prestanda för olika krypteringsalgoritmer inte är densamma. Om så önskas kan du förstås ändra typen av kryptering, men jag är inte säker på att det i alla testade produkter finns en helt identisk uppsättning algoritmer. Vi kommer att testa:

3) eCryptfs är standardsystemet som erbjuds Ubuntu-användare för att kryptera hemkataloger, varför det ingår i detta test. Fungerar ovanpå ett befintligt filsystem. Krypterar varje fil separat, så att alla kan se rättigheterna, datum för ändring, antalet krypterade filer; som standard är filnamn också synliga, även om det finns ett alternativ att kryptera dem. Det minst funktionella verktyget någonsin.

4) EncFS - en ungefärlig analog till eCryptfs, men använder FUSE.

Så en separat maskin av en ganska avancerad ålder valdes ut för tester i följande konfiguration: CPU - Intel Celeron 2000Mhz, RAM - 512 Mb DDR PC2700, systemhårddisk - WD Caviar SE 5400 RPM 80Gb, test HDD - WD Caviar SE 7200 RPM 80 Gb.
OS - Ubuntu 12.04 LTS, versioner av all mjukvara är relevant för lagringsplatserna i detta operativsystem när detta skrivs (Truecrypt 7.1a-linux-x86 kommer inte från arkiven).

Vi kommer att testa standardfilsystemet ext4 för de flesta distributioner. För prestationstestning kommer vi att använda verktyget iozone3 och ett skalskript skrivet "på knäet" för att mäta den procentuella skillnaden i testerna.

Räknemanus. Ingen särskild uppmärksamhet ägnades åt kodens renhet, det enda kriteriet för att skriva var närvaron av det korrekta resultatet.

#!/bin/sh gendifffile () ( #proceduren genererar en fil som är bekväm att tolka. För det första trunkeras rader som inte kan tolkas; för det andra trunkeras de två första siffrorna på varje rad, vilket indikerar #filstorlek och post storlek, respektive ; för det tredje matas hela filen ut rad för rad - #ett testresultat per rad cat $1 | medan du läser LINE ; eko $LINE| grep "^[[:mellanslag:]]*[[:siffra:] ]" | awk "(för (i=3;i<=NF;i++) {print $i}}" done > > $2 ) getline () ( #procedure anger rad nummer $2 i filen $1 head -n $2 "$1" | tail -n 1 ) compare () ( #procedure jämför filen $1 och $2 rad för rad, beräknar den procentuella skillnaden för varje par av test #beräknar sedan aritmetiskt medelvärde, med vilken procent snabbare eller långsammare #fil som innehåller den första gruppen av tester, filen som innehåller den andra gruppen P=0 MAX=0 L1=`cat "$1" | wc -l` #number av tester i filen L2=`cat "$2" | wc -l` if [ $L1 -ne $L2 ]; sedan #om filerna innehåller ett annat antal tester, då kommer vi inte att jämföra dem ekofel return fi STEG =$(($L1*5/100)) J=0 för I i `seq 1 $L1`; gör J=$(($J+1)) om [ $J -eq $STEP ]; sedan J= 0 echo "$((100*$I/$ L1))% avslutad ($I av $L1)" fi A=`getline "$1" $I` B=`getline "$2" $I` if [ `echo $A \> $B|bc -l` - ekv 1]; sedan D=`echo "100-($B*100/$A)"|bc -l` om [ `echo $D \> $MAX| bc -l` -eq "1" ]; sedan MAX=$D sov 5 fi else D=`echo "100-($A*100/$B)"|bc -l` if [ `echo $D \> $MAX| bc -l` -eq "1" ]; sedan MAX=$D sov 5 fi D="-$D" #om värdet har ett "-"-tecken kördes detta test snabbare #i den andra filen än i den första fi P=`echo "$P+ $D"| bc -l`done P=`echo $P/$L1| bc -l` #beräkna det aritmetiska medelekot PERCENT=$P MAX_PERCENT=$MAX ) genaverage () ( #proceduren för att generera en fil förberedd för analys, vars varje rad är det #aritmetiska medelvärdet av motsvarande rader i alla rapporter filer som finns i den analyserade katalogen AVG=` mktemp` F=`ls "$1"|wc -l` #antal filer med rapporter i den angivna katalogen #förutsatt att endast sådana filer lagras där och inget annat #vi kontrollerar inte korrektheten av detta antagande om [ ! -d " $1" -o $F -lt 2 ]; sedan ekofel >/dev/stderr #i denna procedur kommer vi att mata ut alla meddelanden till stderr, eftersom #stdout ersätts med en annan procedur rm -f $AVG exit fi TMP=` mktemp` hitta "$1" -typ f| medan du läser FIL; gör #för varje iozonrapportfil i den givna katalogen I=`mktemp` #gendifffile "$FILE" "$I " #names skriv alla sådana filer till "TMP" rad för rad echo "$I">>$TMP gjort L=`cat \`getline "$TMP" 1\`|wc -l` cat "$TMP"| medan du läser LINE; gör #lite kontroll är bra L1=`cat "$LINE"| wc -l` #innehåller alla filer samma antal tester om [ $L -ne $L1 ]; sedan ekofel >/dev/stderr avsluta fi gjort STEP=$(($L*5/100)) J=0 för I i `seq 1 $L`; gör J=$(($J+1)) om [ $J -eq $STEP ]; sedan eko J=0 "$((100*$I/$L))% klar ($I av $L)" >/dev/stderr fi SUMFILE=`mktemp` #på så sätt får jag värdet på SUM-variabeln från den kapslade slingan SUM=0 cat "$TMP"| medan du läser LINE; gör SUM=$((`getline "$LINE" $I`+$SUM)) echo $SUM > "$SUMFILE" gjort echo `tail -n 1 "$SUMFILE"`/$F|bc -l >> $ AVG #hämta det aritmetiska medelvärdet #och skriv det till lämplig plats #av AVG-filen rm -f "$SUMFILE" klar cat "$TMP"| medan du läser LINE; do #delete temporary files rm -f "$LINE" done rm -f "$TMP" echo $AVG ) printf %b "\\033)