From 6da3e784cd892516b8d80d871d528e7fae10e3ed Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 8 Jun 2022 16:26:04 +0200 Subject: [PATCH] Finish lab --- Lab04/content/part1/analyse/main.go | 21 +++--- Lab04/content/part1/encrypt/main.go | 10 +-- .../images/part1/initAlphabet.png | Bin 40342 -> 0 bytes Lab04/documentation/main.tex | 27 ++----- Lab04/documentation/part1/part1.tex | 70 ++++++++++++++---- Lab04/documentation/part3/part3.tex | 20 ++--- Lab04/documentation/part5/part5.tex | 25 ++++--- Lab04/documentation/part6/part6.tex | 4 +- Lab04/documentation/titlepage/titlepage.tex | 2 +- 9 files changed, 101 insertions(+), 78 deletions(-) delete mode 100644 Lab04/documentation/images/part1/initAlphabet.png diff --git a/Lab04/content/part1/analyse/main.go b/Lab04/content/part1/analyse/main.go index e6decf0..1152a17 100644 --- a/Lab04/content/part1/analyse/main.go +++ b/Lab04/content/part1/analyse/main.go @@ -34,15 +34,14 @@ func (l letterList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } -const LettersInTheAlphabet = 26 -const startUpperCase = 65 +const lettersInTheAlphabet = 'Z' - 'A' + 1 -var letters = make([]letter, LettersInTheAlphabet) +var letters = make([]letter, lettersInTheAlphabet) func initLetterStruct() { - for i := 0; i < LettersInTheAlphabet; i++ { - letters[i].upperCase = string(rune(startUpperCase + i)) - letters[i].lowerCase = string(rune(startUpperCase + i + 32)) + for i := 0; i < lettersInTheAlphabet; i++ { + letters[i].upperCase = string(rune('A' + i)) + letters[i].lowerCase = string(rune('A' + i + 32)) } } @@ -56,7 +55,7 @@ func readFile(relativePath string) string { func countLetters(inputText string) int { totalCount := 0 - for i := 0; i < LettersInTheAlphabet; i++ { + for i := 0; i < lettersInTheAlphabet; i++ { letters[i].count += strings.Count(inputText, letters[i].lowerCase) + strings.Count(inputText, letters[i].upperCase) @@ -66,13 +65,13 @@ func countLetters(inputText string) int { } func calculateFrequency(totalCount int) { - for i := 0; i < LettersInTheAlphabet; i++ { + for i := 0; i < lettersInTheAlphabet; i++ { letters[i].frequency = percent.PercentOf(letters[i].count, totalCount) } } func printResult() { - for i := 0; i < LettersInTheAlphabet; i++ { + for i := 0; i < lettersInTheAlphabet; i++ { l := letters[i] fmt.Printf( "The letter %s (%s) occurs %d times in the text and the frequencyArray in percent is %0.2f\n", @@ -83,14 +82,14 @@ func printResult() { func plotResult() { var count plotter.Values - for i := 0; i < LettersInTheAlphabet; i++ { + for i := 0; i < lettersInTheAlphabet; i++ { count = append(count, float64(letters[i].count)) } p := plot.New() p.Title.Text = "Letter count" p.X.Label.Text = "letter" p.Y.Label.Text = "count" - countBars, err := plotter.NewBarChart(count, vg.Points(LettersInTheAlphabet/2)) + countBars, err := plotter.NewBarChart(count, vg.Points(lettersInTheAlphabet/2)) countBars.Color = plotutil.Color(2) if err != nil { log.Fatalln(err) diff --git a/Lab04/content/part1/encrypt/main.go b/Lab04/content/part1/encrypt/main.go index 2af9b77..00b43ec 100644 --- a/Lab04/content/part1/encrypt/main.go +++ b/Lab04/content/part1/encrypt/main.go @@ -10,11 +10,7 @@ import ( "unicode" ) -const lettersInTheAlphabet = 26 -const startUpperCase = 65 -const endUpperCase = startUpperCase + lettersInTheAlphabet -const startLowerCase = 97 -const endLowerCase = startLowerCase + lettersInTheAlphabet +const lettersInTheAlphabet = 'Z' - 'A' + 1 type keyLetter struct { upperCase string @@ -76,8 +72,8 @@ func encryptMessage(keyWord []keyLetter, message string) string { } else { keyWordIndex := index % len(keyWord) newLetter := letter + keyWord[keyWordIndex].position - if (unicode.IsLower(letter) && newLetter >= endLowerCase) || - (unicode.IsUpper(letter) && newLetter >= endUpperCase) { + if (unicode.IsLower(letter) && newLetter > 'z') || + (unicode.IsUpper(letter) && newLetter > 'Z') { newLetter -= lettersInTheAlphabet } encrypted += string(newLetter) diff --git a/Lab04/documentation/images/part1/initAlphabet.png b/Lab04/documentation/images/part1/initAlphabet.png deleted file mode 100644 index 430dad544fee455813a6639fcb9a4201655e6e33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40342 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 F{{!Ejx+DMq diff --git a/Lab04/documentation/main.tex b/Lab04/documentation/main.tex index febe7b6..36e497d 100644 --- a/Lab04/documentation/main.tex +++ b/Lab04/documentation/main.tex @@ -38,28 +38,11 @@ commentchar=* % comment character } -\lstdefinestyle{mystyle}{ - backgroundcolor=\color{backcolour}, - commentstyle=\color{codegreen}, - keywordstyle=\color{magenta}, - numberstyle=\tiny\color{codegray}, - stringstyle=\color{codepurple}, - emph={int,char,double,float,unsigned,void,bool}, - emphstyle={\color{weborange}}, - basicstyle=\ttfamily\footnotesize, - breakatwhitespace=false, - breaklines=true, - captionpos=b, - keepspaces=true, - numbers=left, - numbersep=5pt, - showspaces=false, - showstringspaces=false, - showtabs=false, - tabsize=2, - firstnumber=1, -} -\lstset{style=mystyle} +\lstset{language=Go, + basicstyle=\ttfamily\scriptsize, + keywordstyle=\color{blue}\ttfamily, + stringstyle=\color{red}\ttfamily, + commentstyle=\color{green}\ttfamily} \setuptoc{toc}{totoc} diff --git a/Lab04/documentation/part1/part1.tex b/Lab04/documentation/part1/part1.tex index 8a0ad39..fbe2383 100644 --- a/Lab04/documentation/part1/part1.tex +++ b/Lab04/documentation/part1/part1.tex @@ -4,23 +4,61 @@ Als Programmiersprache wurde Go\footnote{\href{https://go.dev/}{https://go.dev/}} ausgewählt. Das Analysetool soll jeden Buchstaben eines Textes auf Häufigkeit untersuchen. -Im Prgram wird mit einem Strukt Array gearbeitet. Darin wird der Buchstabe swowohl groß, als auch klein als String abgespeichert. Außerdem wird die dazugehörige Anzahl mit der Häufigkeit abgespeichert. Dadurch kann nach dem Durchlauf der Datensatz einfach sortiert werden. +Im Prgram wird mit einem Array aus Buchstaben-Strukts gearbeitet. -Das Alphabet wird im “Unicode Code Point” genutzt damit es einfach verglichen werden kann. Zum Start des Programmes wird das Alphabet in dem ``letters''-Array initialisiert (Abb. \ref{fig:Initialisierung mit Unicode}). +\begin{lstlisting} + type letter struct { + upperCase string + lowerCase string + count int + frequency float64 + } + type letterList []letter + + func (l letterList) Len() int { + return len(l) + } + + func (l letterList) Less(i, j int) bool { + return l[i].frequency > l[j].frequency + } + + func (l letterList) Swap(i, j int) { + l[i], l[j] = l[j], l[i] + } +\end{lstlisting} -\begin{figure}[H] - \begin{center} - \includegraphics[width=0.6\textwidth]{part1/initAlphabet} - \caption{Initialisierung mit Unicode} - \label{fig:Initialisierung mit Unicode} - \end{center} -\end{figure} +Darin wird der Buchstabe swowohl groß, als auch klein als String abgespeichert. Außerdem wird die dazugehörige Anzahl mit der Häufigkeit abgespeichert. Dadurch kann nach dem Durchlauf der Datensatz einfach sortiert werden. + +Das Alphabet wird im “Unicode Code Point” genutzt damit es einfach verglichen werden kann. Zum Start des Programmes wird das Alphabet in dem ``letters''-Array initialisiert. + +\begin{lstlisting} + var letters = make([]letter, lettersInTheAlphabet) + + func initLetterStruct() { + for i := 0; i < lettersInTheAlphabet; i++ { + letters[i].upperCase = string(rune('A' + i)) + letters[i].lowerCase = string(rune('A' + i + 32)) + } + } +\end{lstlisting} Danach wird die angegebene Datei gelesen und als String geparsed. Der String wird anschließend mit der ``strings.Count''-Funktion gelesen und die gelesene Anzahl im Struct gespeichert. -Wenn alle Buchstaben gelesen wurden, kann die totale Anzahl an Buchstaben genommen werden um die Häufigkeit zu berechnen. +\begin{lstlisting} + func countLetters(inputText string) int { + totalCount := 0 + for i := 0; i < lettersInTheAlphabet; i++ { + letters[i].count += + strings.Count(inputText, letters[i].lowerCase) + + strings.Count(inputText, letters[i].upperCase) + totalCount += letters[i].count + } + return totalCount + } +\end{lstlisting} -Bevor die sortierte Ausgabe erfolgt werden die Daten mit einem Plotter in einer ``barChart.png'' datei gezeichnet (Abb. \ref{fig:Visualisierung von plaintext.txt}). +Wenn alle Buchstaben gelesen wurden, kann die totale Anzahl an Buchstaben genommen werden um die Häufigkeit zu berechnen. Bevor die sortierte Ausgabe erfolgt werden die Daten mit gonum.org/v1/plot/plotter\footnote{\href{https://pkg.go.dev/gonum.org/v1/plot/plotter}{https://pkg.go.dev/gonum.org/v1/plot/plotter}} in einer ``barChart.png'' Datei gezeichnet (Abb. \ref{fig:Visualisierung von plaintext.txt}). \begin{figure}[H] \begin{center} @@ -44,7 +82,11 @@ Zuletzt wird das soriterte Ergebnis ausgegeben (Abb. \ref{fig:Ergebnis von plain \subsection{Verschlüsselung} -Zur verschlüsselung wird ebenfalls “Unicode Code Point” genutzt. Dadurch kann der jeweilige Text einfach um die angegeben Zahl verschoben werden. Dabei zu beachten ist das Ende des Alphabetes, da von vorne begonnen werden muss. Außerdem sind sollten Kleinbuchstaben und Großbuchstaben beachtet werden. Alle Zeichen die keine Buchstaben sind, werden ohne verschlüsselung ausgegeben. Der key lautet ``florianhoss''. +Zur verschlüsselung wird ebenfalls “Unicode Code Point” genutzt. Dadurch kann der jeweilige Text einfach um die angegeben Zahl verschoben werden. Dabei zu beachten ist das Ende des Alphabetes, da von vorne begonnen werden muss. Außerdem sind sollten Kleinbuchstaben und Großbuchstaben beachtet werden. Alle Zeichen die keine Buchstaben sind, werden ohne verschlüsselung ausgegeben. Nach dem Lompilieren kann die Verschlüsselung einfach mit Parametern gestartet werden: + +\begin{verbatim} + ./tool -k florianhoss -f input.txt +\end{verbatim} \subsubsection{Originaler Text (input.txt)} @@ -60,7 +102,7 @@ Zur verschlüsselung wird ebenfalls “Unicode Code Point” genutzt. Dadurch ka \newpage -Das erneute Ausführen der Analyse ergibt eine komplett unterschiedliche Verteilung der Buchstaben (Abb. \ref*{fig:Visualisierung von input.txt} und Abb. \ref*{fig:Visualisierung von output.txt}). +Das erneute Ausführen der Analyse ergibt eine gleichmäßigere Verteilung der Buchstaben (Abb. \ref*{fig:Visualisierung von input.txt} und Abb. \ref*{fig:Visualisierung von output.txt}). Damit ist eine Häufigkeitsanalyse auf den ersten Blick nicht mehr möglich. \begin{figure}[H] \begin{center} @@ -78,4 +120,4 @@ Das erneute Ausführen der Analyse ergibt eine komplett unterschiedliche Verteil \end{center} \end{figure} -Eine Häufigkeitsanalyse kann Hilfreich sein, da in unterschiedlichen Sprachen andere Häufigkeiten auftreten können und damit der Text einfacher analysiert werden kann. +Eine Häufigkeitsanalyse kann Hilfreich sein, da in unterschiedlichen Sprachen andere Häufigkeiten auftreten können und damit der Text einfacher analysiert werden kann. Wenn bei einem Cipher eine Häufigkeitsanalyse erfolgreich durchgeführt werden kann, können Wörter oder Sätze erkannt und entschlüsselt werden. diff --git a/Lab04/documentation/part3/part3.tex b/Lab04/documentation/part3/part3.tex index 8441550..1224fbb 100644 --- a/Lab04/documentation/part3/part3.tex +++ b/Lab04/documentation/part3/part3.tex @@ -1,32 +1,28 @@ \section{Part 3: Symmetric Encryption} -\subsection{Plaintext} - -\begin{verbatim} -This is a small plaintext -\end{verbatim} - \subsection{Verschlüsselter Plaintext} +\begin{verbatim} + Plaintext: This is a small plaintext +\end{verbatim} + \begin{figure}[H] \begin{center} - \includegraphics[width=0.8\textwidth]{part3/plaintext} + \includegraphics[width=0.7\textwidth]{part3/plaintext} \caption{Verschlüsselter Plaintext} \label{fig:Verschlüsselter Plaintext} \end{center} \end{figure} -\subsection{Wort mit 8 Zeichen} +\subsection{8 Zeichen Verschlüsselt mit DES} \begin{verbatim} -FLORIANH x45 + 8 Zeichen: FLORIANH x45 \end{verbatim} -\subsection{Verschlüsselt mit DES} - \begin{figure}[H] \begin{center} - \includegraphics[width=0.7\textwidth]{part3/des} + \includegraphics[width=0.65\textwidth]{part3/des} \caption{Verschlüsselt mit DES} \label{fig:Verschlüsselt mit DES} \end{center} diff --git a/Lab04/documentation/part5/part5.tex b/Lab04/documentation/part5/part5.tex index 1f75989..08d70cc 100644 --- a/Lab04/documentation/part5/part5.tex +++ b/Lab04/documentation/part5/part5.tex @@ -7,7 +7,7 @@ openssl prime -generate -bits 8 \end{verbatim} \begin{verbatim} -prime1 = 211, prime2 = 223, prime3 = 227, e=11 +prime1 = 211, prime2 = 223, e=11 \end{verbatim} \subsection{Berechnungen} @@ -18,29 +18,36 @@ prime1 = 211, prime2 = 223, prime3 = 227, e=11 \end{align} \begin{verbatim} -g = 9, x = 2, y = 3 +g = 9, x = 2, y = 3, n = 227 (prime3) \end{verbatim} \begin{align} - a = g^{x}\ (mod\ prime3) = 9^{2} (mod\ 227) = 81 \\ - b = g^{y}\ (mod\ prime3) = 9^{3} (mod\ 227) = 48 \\ - k_{1} = b^{x}\ (mod\ prime3) = 48^{2}\ (mod\ 227) = 34 \\ - k_{2} = a^{y}\ (mod\ prime3) = 81^{3}\ (mod\ 227) = 34 \\ - k = k_{1} = k_{2} = 34 + a = g^{x}\ (mod\ n) = 9^{2} (mod\ 227) = 81\ (public\ a) \\ + b = g^{y}\ (mod\ n) = 9^{3} (mod\ 227) = 48\ (public\ b) \\ + k_{1} = b^{x}\ (mod\ n) = 48^{2}\ (mod\ 227) = 34\ (private) \\ + k_{2} = a^{y}\ (mod\ n) = 81^{3}\ (mod\ 227) = 34\ (private) \\ + k = k_{1} = k_{2} = 34\ (private) \end{align} \subsection{Fragen und Antworten} 1. What attack is the Diffie-Hellman key exchange vulnerable to? -Man in the Middle +- Man in the Middle 2. What measures can be taken to prevent this type of attack? -Encryption, Authentication over QR code or 2Factor-Authentication +- Encryption, Authentication over QR code or 2Factor-Authentication 3. For the Diffie-Hellman, a generator g is used. Explain what a generator is and how can it be found +- A generator is a number that will be the base of the calculation and is shared between the 2 parties. G is a small prime number. + +\begin{align} + g^{a}\ (mod\ n) \neq g^{b}\ (mod\ n) \\ + g^{(a\ *\ b)}\ (mod\ n) = g^{(b\ *\ a)}\ (mod\ n) +\end{align} + 4. Show why for the primes 61,23 and the public key e=60 no private key d can be found \begin{align} diff --git a/Lab04/documentation/part6/part6.tex b/Lab04/documentation/part6/part6.tex index 2d8d7ed..23901eb 100644 --- a/Lab04/documentation/part6/part6.tex +++ b/Lab04/documentation/part6/part6.tex @@ -17,7 +17,7 @@ pony-ca, admin@pony-ca.de \begin{figure}[H] \begin{center} - \includegraphics[width=0.7\textwidth]{part6/private} + \includegraphics[width=0.8\textwidth]{part6/private} \caption{Private Key} \label{fig:Private Key} \end{center} @@ -25,7 +25,7 @@ pony-ca, admin@pony-ca.de \begin{figure}[H] \begin{center} - \includegraphics[width=0.7\textwidth]{part6/public} + \includegraphics[width=0.9\textwidth]{part6/public} \caption{Public Key} \label{fig:Public Key} \end{center} diff --git a/Lab04/documentation/titlepage/titlepage.tex b/Lab04/documentation/titlepage/titlepage.tex index 5d5e1b9..5f8bcb4 100644 --- a/Lab04/documentation/titlepage/titlepage.tex +++ b/Lab04/documentation/titlepage/titlepage.tex @@ -20,6 +20,6 @@ \vfill \raggedright{} \HRule{13pt}{1pt} \\ - \titleemph{Datum:} 30.05.2022 \\ + \titleemph{Datum:} 08.06.2022 \\ \titleemph{Git:} \href{https://git.unjx.de/flo/SWB6-ITSec/src/branch/master/Lab04}{https://git.unjx.de/flo/SWB6-ITSec/src/branch/master/Lab04} \end{titlepage}