---
# System prepended metadata

title: Security practical labs

---

# 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**;
:::