# Security practical labs ## Lab 1 ### Tarefa 1 ``` k=23 OLA + kkk ------ LIX ``` ### Q1 :::success **LIX** ::: ### Tarefa 2 ``` k=10 LOXPSMKOYWKSYB - kkkkkkkkkkkkkk ------------------ BENFICAEOMAIOR ``` Texto limpo: BENFICAEOMAIOR ### Tarefa 3 O MAR SALGADO, QUANTO DO TEU SAL SAO LAGRIMAS DE PORTUGAL! ### Q2 :::success **$25$** ::: Pois `k=0` é a própria plaintext message. ### Q3 $\frac{25}{2}=12.5$, logo pelo menos :::success **$13$ tentativas** ::: ### Q4 :::success **Cyphertext-only attack (COA)** ::: Pois podemos apenas observar o criptograma e tentando colocar letras mais comuns do alfabeto. ### Tarefa 4 Criptograma:TCZMAHPLTCYHAOXAQOTNTU ### Q5 $26*26*26*26=$ :::success **$456976$** ::: ### Q6 :::success * Chaves com letras todas iguais. * Chaves com uma só letra. ::: ### Tarefa 5 ``` Plaintext message: ISTO * ***** Cyphertext: JUWP G IBELM Cypherkey: K, com K=<.> JUWP G IBELM - <.>< . ><.>< ------------------ ISTO * ***** JUWP G IBELM - ISTO * ***** ------------------ ABCA * ***** Visto que a chave tem apenas 3 letras, K=ABC, logo: JUWP G IBELM - ABCA B CABCA ------------------ ISTO E FACIL ``` ### Q7 :::success **Known-plaintext attack (KPA)** ::: Pois temos um par (parcial) de plaintext-message e cyphertext. ### Tarefa 6 ```c= //includes #include<stdio.h> #include<string.h> #include<stdbool.h> #include<stdlib.h> //definitions #define ALPHABET_SIZE 26 #define WORD_SIZE 12 //functions ssize_t getKeyOfAlphabet(char letter,char* alphabet,size_t alphabetSize){ for(size_t i=0;i<alphabetSize;i++){ if(alphabet[i]==letter){ return i; } } return -1; } void encrypt(char *in,char *out,size_t size,char *normalAlphabet,char*substitutedAlphabet){ if(strlen(in)!=strlen(out)){ perror("Invalid sizes for words! Must be the same"); exit(-1); } for(size_t i=0;i<size-1;i++){ ssize_t temp=substitutedAlphabet[getKeyOfAlphabet(in[i],normalAlphabet,ALPHABET_SIZE)]; if(temp==-1){ perror("There was an error encrypting"); exit(-1); } out[i]=temp; } } void decrypt(char *in,char *out,size_t size,char *normalAlphabet,char*substitutedAlphabet){ if(strlen(in)!=strlen(out)){ perror("Invalid sizes for words! Must be the same"); exit(-1); } for(size_t i=0;i<size-1;i++){ ssize_t temp=normalAlphabet[getKeyOfAlphabet(in[i],substitutedAlphabet,ALPHABET_SIZE)]; if(temp==-1){ perror("There was an error encrypting"); exit(-1); } out[i]=temp; } } void showMenu(void){ printf("What do you want to do?\n"); printf("1-Encrypt\n"); printf("2-Decrypt\n"); printf("0-Exit\n"); } int main(void){ char NORMAL_ALPHABET[ALPHABET_SIZE] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}; char SUBSTITUTED_ALPHABET[ALPHABET_SIZE] = {'S','Q','T','U','H','J','I','B','Y','K','A','V','L','C','W','E','Z','N','R','M','X','G','F','P','D','O'}; char plaintext[WORD_SIZE] = "OLACOMOESTA"; char cyphertext[WORD_SIZE] = "XXXXXXXXXXX"; char plaintext2[WORD_SIZE] = "XXXXXXXXXXX"; char cyphertext2[WORD_SIZE] = "WVSTWLWHRMS"; while(true){ showMenu(); int option; scanf("%d",&option); if(option==1){ encrypt(plaintext,cyphertext,WORD_SIZE,NORMAL_ALPHABET,SUBSTITUTED_ALPHABET); printf("%s->%s\n",plaintext,cyphertext); } else if(option==2){ decrypt(cyphertext2,plaintext2,WORD_SIZE,NORMAL_ALPHABET,SUBSTITUTED_ALPHABET); printf("%s->%s\n",cyphertext2,plaintext2); } else if(option==0){ break; } else{ perror("Invalid option!"); } } return 0; } ``` ### Q8 :::success $26!$ ::: Pois cada chave é constituida pelo alfabeto de 26 letras, que não se podem repetir. ### Q9 $26!=403291461126605635584000000$ chaves possiveis. Assumindo que um computador consegue testar uma chave em cada operação composta e que um computador moderno consegue efetuar cerca de $2^{26}$ operações compostas num segundo: $\text{Operações compostas por segundo}=2^{26}=67108864$ $\text{Operações compostas por minuto}=2^{26}*60=4026531840$ $\text{Operações compostas por hora}=2^{26}*60*60=241591910400$ $\text{Operações compostas por dia}=2^{26}*60*60*24=5798205849600$ $\text{Operações compostas por mês}=2^{26}*60*60*24*31=179744381337600$ $\text{Operações compostas por ano}=2^{26}*60*60*24*31*12=2156932576051200$ $\text{Operações compostas por século}=2^{26}*60*60*24*31*12*100=215693257605120000$ $\text{Séculos para decrifrar cifra de substituição}=\frac{403291461126605635584000000}{215693257605120000}\approx186974533003$ :::success **Não, não conseguia.** ::: ### Q10 :::success **Em termos de número de chaves, parece-me ser segura, mas em termos de facilidade de ataque, não.** ::: ### Q11 ``` Dados, e.g.: a1=[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ | | | | | | | | | | | | | | | | | | | | | | | | | | a2=[S,Q,T,U,H,J,I,B,Y,K,A,V,L,C,W,E,Z,N,R,M,X,G,F,P,D,O] Dada a frase: ATARTARUGA O texto cifrado seria: SMSNMSNXIS Se se soubesse que *TAR****** correspondia a SMSNMSNXIS, saberiamos que todos os S correspondem a A, todos os M correspondem a T e todos os N correspondem a R, logo saberiamos que na verdade que: A frase: ATARTAR**A O texto cifrado seria: SMSNMSNXIS ``` Na demonstração atrás, descobriu-se alguma coisa, logo sofre do primeiro ataque. Também sofre da segunda, visto que as letras do texto cifrado correspondem as do texto original diretamente, logo consegue-se perceber quantas letras iguais existem. :::success **Sim, é vulnerável em ambas as situações.** ::: ### Q12 ```python= #enigmaTime.py for i in range(712882560+1): pass ``` ``` time python3 enigmaTime.py -------- real 0m19.516s user 0m19.510s sys 0m0.000s ``` :::success **$\approx 19.5$ segundos** ::: ### Tarefa 7 ![](https://i.imgur.com/KrEEhft.png) ### Q13 :::success **9** ::: ### Q14 :::success **7** ::: ### Q15 :::success **4** ::: ### Q16 :::success **5** ::: ### Q17 :::success **Não, não ia** ::: Como sao eventos independentes, a probabilididade de sair cara ou coroa na sétima tentativa continuaria a ser $\frac{1}{2}$ ### Q18 :::success **Sim, vai.** ::: ### Q19 :::success **Aleatória** ::: ### Tarefa 8 ``` 0101000011010011 ⊕ 0000000100000001 --------------------- 0101000111010010 ``` ### Q20 :::success **9** ::: ### Q21 :::success **7** ::: ### Q22 :::success **3** ::: ### Q23 :::success **2** ::: ### Q24 :::success **Sim, de facto parece** ::: ### Q25 :::success **É impossível obter o texto-limpo de volta, a não ser que também lhe envie a sequência resultante da minha experiência.** ::: ## Lab 2 ### Tarefa 1 e Q1 :::success **O *openssl* é uma biblioteca de criptografia utilizada para certas comunicações. Pode ser utilizada na linha de comandos ou embutida em certas linguagens de programação, como C.** ::: ### Q2 :::success **O OpenSSL é importante mas não há nada a reportar acerca de bugs severos, em termos de segurança, na sua implementação** ::: Apesar de não ter tido bugs severos que íam fazendo com que a Internet fosse com o bodo, teve, sim, bastantes vulnerabilidades. ### Q3 :::success **Escrevendo `man command` no terminal...** ::: ### Q4 :::success **Sim, há... um é um toolkit e o outro é um comando de linux.** ::: ### Q5 :::success **Sim** ::: ### Q6 :::success **Claro** ::: ### Q7 :::success **Também dá** ::: ### Q8 :::success **FAZ TUDO!** ::: ### Q9 :::success **Não, mas de resto faz tudo...** ::: ### Tarefa 2 ``` openssl rand -hex 10 ``` ### Tarefa 3 ``` openssl ``` ### Q10 :::success **Não** ::: Estou agora num interpretador de comandos de openssl. ### Q11 ``` help ``` :::success **Sim** ::: ### Q12 :::success **48** ::: ### Q13 :::success * **`-in <file>`**; * **`-out <file>`**; * **`-pass <arg>`**; * **`-e`**; * **`-d`**; * **`-a/-base64`**; * **`-k`**; * **`-kfile`**; * **`-md`**; * **`-S`**; * **`-K/-iv`**; * **`-[pP]`**; * **`-bufsize <n>`**; * **`-nopad`**. ::: ### Q14 :::success **Só não fala como as pessoas!** ::: ### Tarefa 4 ``` openssl enc -rc4 -e -K abcdefg0123456789 -in plaintext -out ciphertext.rc4 ``` ### Q15 :::success **R**ivest **C**ipher **4** ::: ### Q16 :::success **Sim, parece** ::: Porque tem muita entropia. ### Q17 :::success **Não, não funcionou. :(** ::: Porque a chave tem que ser hexadecimal e a chave dada no comando tem um g. Corrige-se para: ``` openssl enc -rc4 -e -K abcdef0123456789 -in plaintext -out ciphertext.rc4 ``` ### Q18 :::success **Sim, já verifiquei usando `cat ciphertext.rc4` e o que lá encontrei não faz sentido nenhum.** ::: ### Q19 ## Lab 4 ### Q1 :::success **$u=log_b(n)$** ::: ### Tarefa 1 ```c= #include <stdio.h> #include <math.h> int main(int argc,char *argv[]){ size_t numberSymbols=0; double entropyValue=0; //check for invalid flags if(argc!=2){ perror("Invalid flags!"); return -1; } //open file FILE *fp=fopen(argv[1],"r"); if(fp==NULL){ puts("cannot open file"); return -1; } //initialize each character probability to 0 int asciiProbabilities[255]; for(size_t i=0;i<255;i++){ asciiProbabilities[i]=0; } //read each character of the file, //incrementing the number of seen by each character in the ascii array char readChar=1; while((readChar=fgetc(fp))!=EOF){ numberSymbols++; asciiProbabilities[(unsigned char)readChar]++; } //calculate entropy for(size_t i=0;i<255;i++){ double eachCharacterProbability=(double)asciiProbabilities[i]/numberSymbols; if(eachCharacterProbability>0){ entropyValue-=eachCharacterProbability* log((float)eachCharacterProbability); } } printf("\n\tThe entropy value for file %s is\n\n \t\t\t%f \n",argv[1],entropyValue); printf("\n\tThe max entropy value is %f \n\n",log((double)256)); fclose(fp); } ``` ### Q2 :::success **256** ::: Pois essa é a quantidade de valores na tabela ASCII, o que é a quantidade possível de valores no ficheiro. ### Q3 :::success **5.55** ::: Pois $log_b(256)\approx 5.55$ ### Tarefa 2 e Tarefa 3 e Tarefa 4 e Tarefa 5 ``` zip passwords.zip passwords ``` ``` openssl enc -aes-128 -in passwords -out passwords.aes -K 62ee86b4dc34742afc452f1a2b90e831 -iv e1a1aa1a178faf6d74115ff09dac809d ``` ``` openssl enc -aes-128 -in passwords.zip -out passwords.zip.aes -K 62ee86b4dc34742afc452f1a2b90e831 -iv e1a1aa1a178faf6d74115ff09dac809d ``` ``` zip passwords.aes.zip passwords.aes ``` | Name | Size (KB) | Entropy | | -------- | -------- | -------- | | passwords | 1.5 | 3.223813 | | passwords.zip | 0.97 | 4.491682 | | passwords.aes | 1.5 | 4.381308 | | passwords.zip.aes | 0.97 | 3.028029 | | passwords.aes.zip | 1.7 | 4.484435 | ### Q4 :::success **Cipher Block Chaining** ::: Visto que requer um vetor de inicialização. ### Q5 :::success **128 bits** ::: Porque $16$ bytes = $128$ bits. ### Q6 :::success **Primeiro comprimir e depois cifrar.** ::: Ao comprimir o ficheiro original, este irá conter diversos padrões, que poderão ser utilizados para uma maior redução do ficheiro. Se cifrarmos primeiro, muitos destes padrões serão perdidos, o que, não só, poderá fazer com que a compressão não faça nada, mas poderá, inclusive, aumentar o tamanho do ficheiro, devido à adição do cabeçalho de compressão. ### Tarefa 6 ``` openssl enc -aes-128-ecb -in plaintext -out cyphertext.ecb -K 11232233 ``` ### Tarefa 7 ``` hexdump -C cyphertext.ecb ``` ``` 00000000 fb 5d 84 63 be 29 f4 48 9e 5d 70 ec f8 e4 ff 80 |.].c.).H.]p.....| 00000010 4b cf 7a d4 3c d4 c0 f2 a2 0f 74 76 57 87 54 98 |K.z.<.....tvW.T.| 00000020 00 e1 74 34 22 5a 94 e2 59 10 d5 6c 0e d9 d2 19 |..t4"Z..Y..l....| 00000030 fb 5d 84 63 be 29 f4 48 9e 5d 70 ec f8 e4 ff 80 |.].c.).H.]p.....| 00000040 0a 1a e9 c0 2c e4 7d 86 45 63 76 65 f3 da 99 d0 |....,.}.Ecve....| 00000050 ``` ### Q7 :::success **A**dvabced **E**ncryption **S**tandard ::: ### Q8 :::success **Cifra de chave simétrica por blocos.** ::: ### Q9 :::success **Sim** ::: ### Q10 :::success **$16$ bytes** ::: Porque $128$ bits = $16$ bytes. ### Q11 :::success Não, não precisa. ::: ### Tarefa 8 ``` openssl enc -aes-128-cbc -K 11232233 -in plaintext -out cyphertext.cbc ``` ### Q12 :::success **Digo, digo.** ::: ### Q13 :::success **Adicionando um vetor de inicialização** ::: Pois o modo cbc necessita de um iv para cifrar o primeiro bloco. ``` openssl enc -aes-128-cbc -K 11232233 -in plaintext -out cyphertext.cbc -iv 0 ``` ### Q14 :::success **C**ypher **B**lock **C**haining ::: ### Q15 :::success **Um modo de utilização de uma cifra** ::: ### Tarefa 9 ``` hexdump -C cyphertext.cbc ``` ### Q16 :::success **Que interessante, não vejo qualquer padrão** ::: ### Q17 :::success **Os dois criptogramas seriam totalmente distintos** ::: Porque o primeiro bloco vai ser afetado pelo iv, o que significa que todos os blocos consequentes também serão. ## Lab 5 ### Tarefa 1 ``` openssl dgst -md5 PodiaSerAFreqMasNaoE.pdf > PodiaSerAFreqMasNaoE.md5 ``` ``` openssl dgst -sha1 PodiaSerAFreqMasNaoE.pdf > PodiaSerAFreqMasNaoE.sha1 ``` ### Q1 :::success **Iguanas** ::: ### Q2 :::success * **Que, neste caso, o ficheiro que chegou à minha máquina não sofreu erros durante a transmissão.** * **Que, neste caso e confiando no que o Professor afirmou, o ficheiro que descarreguei é, de facto, o ficheiro que está no servidor, e para o qual calculou os valores de hash** ::: ### Q3 :::success **Ron Rivest** ::: ### Q4 ### Q5 :::success **MD5 : 128** **SHA1: 160** ::: ### Q6 :::success **S**ecure **H**ash **A**lgorithm **1** ::: ### Q7 :::success **M**essage **D**igest **5** ::: ### Q10 :::success * **Integridade dos dados**; * **Identificação de burlas em ficheiros descarregados da Internet**. ::: ### Q12 :::success **Os valores de hash ficaram totalmente diferentes** ::: ### Q13 :::success **Mudaram aproximadamente 1/2 dos bits** ::: ### Q14 :::success **Obtínhamos exatamente o mesmo comportamento que observamos quando mudamos 1 só byte** ::: ### Q15 :::success **Não. As alterações produzidas parecem ser aparentemente imprevisíveis** ::: ### Q16 :::success **Não estou a ver como iria fazer isso para já, mas creio que iria conseguir. A minha ideia era a seguinte** ::: É teóricamente possível com *bruteforce*, mas é, porém, quase impossível, i.e., praticamente impossível. ### Q17 :::success **Resistência a colisões** ::: ### Q18 :::success **Se não, procure explicar** ::: Porque, $\frac{2^{160}}{2^{28}}=5.444517870735016e+39$, o que é big número, impossível de fazer em tempo útil, sendo $2^28$ número de operações dum computador em tempo útil e $2^160$ número de hashes do sha-1. ## Lab 6 ## Q1 :::success **8 bytes** ::: ## Q2 :::success **` cc programa.c -lcrypto`** ::: ### Q4 :::success **`javac sha1sum.java`** ::: ## Lab 7 ### Q1 :::success **M**essage **A**uthentication **C**ode ::: ### Tarefa 1 ``` echo -n "arrozDePato" > plaintext ``` ``` openssl dgst -sha1 plaintext > plaintext.sha1 ``` ``` openssl enc -aes128 -in plaintext.sha1 -out plaintext.sha1.aes -K 5555ffff1234aedf9876cbcb6546789e -iv 7e5766d419adfbc5859e7a48cfe9821d ``` ### Tarefa 2 ``` openssl enc -aes128 -d -in plaintext.sha1.aes -out deciphered.sha1 -K 5555ffff1234aedf9876cbcb6546789e -iv 7e5766d419 adfbc5859e7a48cfe9821d ``` ``` openssl dgst -sha1 plaintext > plaintextNewHash.sha1 ``` ``` diff plaintextNewHash.sha1 plaintext.sha1 ``` ### Q4 :::success **Todos os que possuem a chave secreta** ::: ### Q5 :::success * **Garantia de que o ficheiro não sofreu erros aleatórios durante a transmissão (integridade)**; * **Garantia de que o ficheiro não foi alterado intencionalmente durante a transmissão (autenticação da origem da informação)** ::: ### Tarefa 3 e Q6 :::success **Sim, é, com um só comando: `openssl dgst -sha1 -hmac 5555ffff1234aedf9876cbcb6546789e plaintext > plaintext.hmac`** ::: ### Q7 :::success **Hash** ::: ### Tarefa 4 ``` openssl dgst -sha1 -hmac 5555ffff1234aedf9876cbcb6546789e plaintext > plaintext2.hmac ``` ``` diff plaintext.hmac plaintext2.hmac ``` ### Q8 :::success **Não, não é. Mas o 3 já é!** ::: ### Q9 :::success **14** ::: Por Tentativa e erro #### Q10 :::success **Sim, concordo, porque o atacante apenas conseguia escutar as comunicações** ::: ## Lab 8 ### Tarefa 1 ``` p=13 q=17 N=221 FIN=192 e=5 d=77 pk=(e,N)=(5,221) sk=(d,N)=(77,221) ``` ### Tarefa 2 ``` Para 69 encrypted=205 decrypted=69 ``` ### Q1 :::success **Não, e não há qualquer problema de segurança nisso** ::: ### Q2 :::success **Porque eu lha dei diretamente** ::: ### Q3 :::success **Hummm.... não** ::: ### Q4 :::success **A chave pública** ::: ### Q5 :::success **A chave privada** ::: ### Tarefa 4 ``` openssl genrsa -out myPrivateKey 1024 ``` ``` openssl rsa -in myPrivateKey -pubout -out myPublickey ``` ``` openssl genrsa -out myPrivateKey -aes128 1024 ``` ``` openssl rsa -in myPrivateKey -pubout -out myPublickey ``` ### Tarefa 5 ``` openssl rsautl -in secretKey -out secretKey.rsa -pubin -inkey myPublickey -encrypt ``` ``` openssl rsautl -in secretKey.rsa -out secretKey2 -inkey myPrivateKey -decrypt ``` ### Q6 :::success **Neste caso consegui, porque 128 bits é menor do que o tamanho do módulo que estou a usar** ::: ### Q7 :::success **1024** ::: ### Q8 :::success **Não. O texto é grande demais e o OpenSSL não deixa cifrar por blocos usando o RSA, visto que este modo (livro de escola), por sí só, já é inseguro.** ::: ### Q9 :::success **Pretty good privacy** ::: ### Tarefa 9 ``` openssl rsautl -sign -inkey myPrivateKey -in portugal.sha256 -out portugal.sha256.sig ``` ``` openssl rsautl -verify -pubin -inkey myPublickey -in portugal.sha256.sig -out portugal2.sha256 ``` ``` diff portugal.sha256 portugal2.sha256 ``` ### Tarefa 10 ``` openssl dgst -sha256 -sign myPrivateKey -out portugal.sig portugal.txt ``` ``` openssl dgst -sha256 -verify myPublickey -signature portugal.sig portugal.txt ``` ### Q11 :::success **Só quem possui a chave privada** ::: ### Q12 :::success **Só quem possui a chave simétrica secreta** ::: ### Q13 :::success **Só quem possui a chave pública** ::: ### Q14 :::success **Só quem possui a chave simétrica secreta** ::: ### Q15 :::success * **Autenticação da origem da informação**; * **Integridade**; * **Não repúdio**; * **Autenticidade**; * **Dificuldade de falsificação**. ::: ### Q16 :::success * **Integridade**; * **Autenticidade**; :::