Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
efinf:blc2016:krypto [2017/01/05 13:48]
Ivo Blöchliger [Hash-Funktionen]
efinf:blc2016:krypto [2017/01/26 09:30] (current)
Ivo Blöchliger
Line 1: Line 1:
 {{backlinks>.}} {{backlinks>.}}
 ===== Prinzipien moderner Kryptographie ===== ===== Prinzipien moderner Kryptographie =====
 +==== Zusammenfassung ====
 +
 +  * Slides: {{ :efinf:blc2016:26.01.17_0742.pdf |}}
 + 
 +
 Begriffe:  Begriffe: 
   * **{{https://de.wikipedia.org/wiki/Kryptologie|Kryptologie}}** = {{https://de.wikipedia.org/wiki/Kryptographie|Kryptographie}} (Verschlüsseln) und {{https://de.wikipedia.org/wiki/Kryptoanalyse|Kryptoanalyse}} (gegnerisches Entschlüsseln)   * **{{https://de.wikipedia.org/wiki/Kryptologie|Kryptologie}}** = {{https://de.wikipedia.org/wiki/Kryptographie|Kryptographie}} (Verschlüsseln) und {{https://de.wikipedia.org/wiki/Kryptoanalyse|Kryptoanalyse}} (gegnerisches Entschlüsseln)
Line 35: Line 40:
   * Ein Hashwert kann auch mit Ruby-Libraries berechnet werden, {{https://ruby-doc.org/stdlib-2.1.0/libdoc/digest/rdoc/Digest.html|siehe z.B. hier}}. Das ist sehr viel schneller.   * Ein Hashwert kann auch mit Ruby-Libraries berechnet werden, {{https://ruby-doc.org/stdlib-2.1.0/libdoc/digest/rdoc/Digest.html|siehe z.B. hier}}. Das ist sehr viel schneller.
   * Das Histogramm kann als csv-Datei exportiert werden, wobei jede Zeile so aussieht: '128;423' (Erster Eintrag: Anzahl Bits, zweiter Eintrag: Anzahl Vorkommnisse).   * Das Histogramm kann als csv-Datei exportiert werden, wobei jede Zeile so aussieht: '128;423' (Erster Eintrag: Anzahl Bits, zweiter Eintrag: Anzahl Vorkommnisse).
 +
 +<hidden Lösungsansatz>
 +Hinweis: Code herunterladen, nicht kopieren.
 +<code ruby hashtest.rb>
 +require 'digest'
 +
 +# s: String, bit: nummer
 +def flipBit(s, bit)
 +    # Kopie von s
 +    s = String.new(s)
 +    byte = bit/8;
 +    bit = bit%8;
 +    s.setbyte(byte,
 +      s.getbyte(byte)^(1 << bit))
 +    return s
 +end
 +
 +# s1,s2: Zwei gleich lange Strings
 +def count_bit_diff(s1,s2)
 +    diff = 0
 +    s1.size.times{|i|
 +      xor = s1.getbyte(i)^s2.getbyte(i)
 +      # Ganzzahl: 1 Byte
 +      8.times{|bit|
 +        diff+=1 if (xor & (1<<bit))!=0
 +      }
 +    }
 +    return diff
 +end
 +
 +text = File.read("hashtest.rb")
 +hash_orig = Digest::SHA256.digest(text)
 +counters = Array.new(256,0)
 +(text.size*8).times{|bit|
 +    modif = flipBit(text, bit);
 +    hash_modif = Digest::SHA256.digest(modif)
 +    counters[count_bit_diff(hash_orig, hash_modif)]+=1
 +}
 +
 +# Generate CSV-Output
 +counters.each_with_index{|c,i|
 +        puts "#{i};#{c}"
 +}
 +</code>
 +Das Historgramm kann wie folgt erzeugt werden:
 +<code bash>
 +ruby hashtest.rb > test.csv
 +libreoffice test.csv
 +</code>
 +In LibreOffice ist der Strichpunkt (Semicolon) als Trennzeichen zu wählen. Das Histogramm kann als Balkendiagramm erzeugt werden, wobei die erste Spalte als Labels verwendet wird.
 +
 +{{:efinf:blc2016:histogramm-sha256.png?direct&200|}}
 +</hidden>
  
 === Anwendungen === === Anwendungen ===
Line 42: Line 100:
   * Digitale Unterschrift: Anstatt das ganze Dokument zu signieren, wird der Hash davon signiert (ist erheblich schneller).   * Digitale Unterschrift: Anstatt das ganze Dokument zu signieren, wird der Hash davon signiert (ist erheblich schneller).
   * Blockchain, für z.B. Bitcoins.   * Blockchain, für z.B. Bitcoins.
 +  * Überprüfen von Plagiaten. Nicht die Inhalte sondern Hashes (wahrscheinlich von Sätzen, Abschnitten, Seiten, ganzer Text) werden gespeichert. Beim Wiederfinden dieser Hashes kann auf die Original-Arbeit verwiesen werden.
  
 === Rainbow-Tables === === Rainbow-Tables ===
 Trade-Off: Speicherplatz/Rechenpower. Trade-Off: Speicherplatz/Rechenpower.
  
-Zutaten: Bakannte Hash-Funktion $h(s)$, Spezielle Hash-ähnliche Funktion $p(h)$, die aus Hashes Passwörter generiert.+Zutaten: Bakannte Hash-Funktion $h(s)$, Spezielle Hash-ähnliche Funktionen $p_i(h)$, die aus Hashes Passwörter generieren. 
 +Diese Funktionen können einander sehr ähnlich sein. Z.B. fassen die Funktionen den Hash als Ganzzahl auf, rechnen i dazu und dann modulo die Anzahl Passwörter im betrachteten Passwortraum und liefern das entsprechende Passwort (z.B. 0 ist 'aaaaa').
  
 Generierung der Tabelle: Generierung der Tabelle:
   - Starte mit einem Passwort $x$.   - Starte mit einem Passwort $x$.
   - Speichere das Passwort $x$   - Speichere das Passwort $x$
-  - Wiederhole $n$ mal (so $10^6$ oder so): $x := p(h(x))$+  - Für $i$ von 0 bis $(n-1)$ mal (so $10^4$ oder so): $x := p_i(h(x))$
   - Speichere $h(x)$   - Speichere $h(x)$
   - Wiederhole ab Schritt 2.   - Wiederhole ab Schritt 2.
  
 Entschlüsseln eines Passworts, gegeben Hash $y$. Entschlüsseln eines Passworts, gegeben Hash $y$.
-  - Wiederhole bis $yin der Tabelle vorkommt (maximal $n$ mal ($n$ wie oben)) +  - Für $jvon $n$ bis zu 0 hinunter: 
-    - Setzte $y := h(p(y))$ +    - Fasse $h$ als Eintrag in Spalte $j$ auf und rechne die Kette zu Ende (beginnend mit $p_j(h)$). 
-  - Wenn $y$ nicht in der Tabelle vorkommt, Passwort ist nicht in der Rainbow-Table+    - Wenn das Ende der Kette in der Tabelle vorkommt, die ganze Kette neu rechnen. Hoffen, dass der gesuchte Hash in der Kette ist (es ist nicht unwahrscheinlich, dass zwei verschiedene Startpasswörter zum gleichen Hash am Ende führen)
-  - Wenn $yin der Rainbow-Table ist, vom Startpasswort startenbis passendes Passwort gefunden.+ 
 + 
 +Ursprünglich hatte man diverse Tabellen mit unterschiedlichen Reduktionsfunktionen $p_i(h)$, um das Zusammenlaufen von Ketten zu vermeiden.  
 + 
 +Siehe http://lasec.epfl.ch/pub/lasec/doc/Oech03.pdf  (ist offenbar eine Erfindung aus Lausanne ;-)) 
 + 
 + 
 +=== Spielzeug Beispiel === 
 +<hidden Code zur Abschätzung des Rechenaufwands> 
 +<code ruby rainbowtable.rb> 
 +require 'digest' 
 + 
 +# Passwords are 7 lower case letters a-z 
 +# Hash is SHA256 
 + 
 +# Makes a password out of a hex hash 
 +def makePW(hashn=7) 
 +  z = hash.to_i(16) 
 +  pw = "" 
 +  n.times{ 
 +    pw += (z % 26 + 'a'.ord).chr 
 +    z/=26 
 +  } 
 +  return pw 
 +end 
 + 
 +#Random password (for starting a chain) 
 +def randPass(n=7) 
 +  Array.new(n){('a'.ord+rand(26)).chr}.join   
 +end 
 + 
 +# Checkhow many hashes per second/minute/hour can be computed 
 +def speedTest(n=5) 
 +  text = "a"*5 
 +  n = 26**text.size 
 +  start = Time.now 
 +  n.times { 
 +    Digest::SHA256.hexdigest(text) 
 +    text.succ! 
 +  } 
 +  total = Time.now-start 
 +  puts "#{n} Hashes in #{total} secs." 
 +  puts "Makes #{(n/total).to_i} hashes/s" 
 +  puts "Makes #{(n/total*60).to_i} hashes/min" 
 +  puts "Makes #{(n/total*3600).to_i} hashes/h" 
 +end 
 + 
 + 
 +</code> 
 +</hidden>
 ===== Public-Private Key Encryption ===== ===== Public-Private Key Encryption =====
 +
 +{{ :efinf:blc2016:17.01.17_1355.pdf |}}
  
 ==== Mathematische Grundlagen ==== ==== Mathematische Grundlagen ====
-  * Rechnen in Restklassen +  * Rechnen in Restklassen: Nach jeder Operation wird der Rest modulo n (der Modulus) gerechnet. 
-  * Potenzieren in $\mathbb{Z} / n\mathbb{Z}$+  * Potenzieren in $\mathbb{Z} / n\mathbb{Z}$ (d.h. modulo n).
   * Diskreter Logarithmus ist schwierig   * Diskreter Logarithmus ist schwierig
  
 +$b^e \mod n$ effizient ausrechnen. Annahme: $e$ liegt im Zweiersystem vor, z.B. 0b10001011. Dann ist
 +$$b^e = b^{1+2+8+128} = b^1 \cdot b^2 \cdot b^8 \cdot b^{128}$$
 +
 +Die Potenzen $b^2$, $b^4$, $b^8$, $b^{16}$, etc. können durch wiederholtes quadrieren erhalten werden.
 +
 +=== Pseudo-Code zum Potenzieren ===
 +  * **Input** $b$, $e$, $n$
 +  * **Output** $r=b^e \mod n$
 +  * $r=1$
 +  * Solange $e \neq 0$:
 +    * Falls Bit 0 von $e$ gesetzt (d.h. wenn ''e & 1 == 1'')
 +      * $r := r \cdot b \mod n$
 +    * $e := e/2$ (bzw. ''e= e >> 1'')
 +    * $b := b^2 \mod n$
 +  * Resultat ist $r$
 +
 +<hidden Ruby-Code>
 +<code ruby modpow.rb>
 +def modpow(b,e,n)
 +  res = 1
 +  while (e>0)
 +    if e & 1 == 1
 +      res = (res*b)%n
 +    end
 +    e = e >> 1
 +    b=(b*b)%n
 +  end
 +  return res
 +end
 +</code>
 +</hidden>
 +==== Diffie-Hellmann Key-Exchange ====
 +Achtung: Nicht jede Primzahl und nicht jede Basis ist dafür geeignet. Die sollten sorgfältig ausgewählt werden, was Rechenaufwand bedeutet. Das ist der Grund, warum viele Internetdienste gleiche Primzahlen und Basen verwenden.
 +
 +Siehe z.B. https://de.wikipedia.org/wiki/Diffie-Hellman-Schl%C3%BCsselaustausch
 +
 +==== RSA-Schlüssel zum Spielen (hier 32 Bit, bietet keine Sicherheit) ====
 +<code bash>
 +# 32 bit Schlüssel generieren
 +openssl genrsa 32 > key.pem
 +
 +# Daten anzeigen (dezimal und hexadezimal)
 +openssl rsa -text -noout < key.pem
 +
 +# Public key schreiben
 +openssl rsa -in key.pem -outform PEM -pubout > public.pem
 +
 +
 +</code>
 +
 +Zutaten: Modulus $n$ (Produkt zweier Primzahlen), öffentlicher Exponent $o$ (normalerweise 65537 = 0x10001), privater Exponent $p$.
 +
 +Eigenschaft: $$\left(x^o\right)^p \mod n= x \mod n = \left(x^p\right)^o \mod n$$
 ==== Public/private-Key Verschlüsselung ==== ==== Public/private-Key Verschlüsselung ====
  
Line 80: Line 244:
 Effektiv wird normalerweise nur ein Hash der Nachricht verschlüsselt. Effektiv wird normalerweise nur ein Hash der Nachricht verschlüsselt.
  
-=== Authetifizierung ===+=== Authentifizierung ===
 Zuordnung Schlüssel-Person (oder Server) muss überprüft werden. Ansätze:  Zuordnung Schlüssel-Person (oder Server) muss überprüft werden. Ansätze: 
   * Austausch über weiteren Kanal (z.B. in Person, Austausch auf Papier).   * Austausch über weiteren Kanal (z.B. in Person, Austausch auf Papier).
   * Zertifizierung über vertrauenswürdige Drittstelle. Diese signiert, dass der Schlüssel zur Person (oder Server) gehört.    * Zertifizierung über vertrauenswürdige Drittstelle. Diese signiert, dass der Schlüssel zur Person (oder Server) gehört. 
  
-==== Schlüsseltausch über unsicheren Kanal (Diffie-Hellman) ==== 
  
 ==== OTR, Deniability, Forward Secrecy ==== ==== OTR, Deniability, Forward Secrecy ====
   * https://en.wikipedia.org/wiki/Off-the-Record_Messaging   * https://en.wikipedia.org/wiki/Off-the-Record_Messaging
- 
  • efinf/blc2016/krypto.1483620524.txt.gz
  • Last modified: 2017/01/05 13:48
  • by Ivo Blöchliger