# RC4

Em criptografia, RC4 (ou ARC4, de Alleged RC4, ver abaixo) era o algoritmo simétrico de criptografia de fluxo mais usado no software e era utilizado nos protocolos mais conhecidos, como Secure Socket Layers (SSL, hoje conhecido como TLS) (para proteger o tráfego Internet) e WEP (para a segurança de redes sem fios, obsoleto, hoje se usa o WPA). O RC4 não é considerado um dos melhores sistemas criptográficos pelos adeptos da criptografia, e em algumas aplicações podem converter-se em sistemas muito inseguros. No entanto, alguns sistemas baseados em RC4 são seguros o bastante num contexto prático.

## História

Em 1987 Ronald Rivest desenvolveu o algoritmo RC4 para a empresa RSA Data Security, Inc., líder mundial em algoritmos de criptografia. Foi, durante tempos, um segredo comercial muito bem guardado, muito popular, e utilizado largamente em software, como Lotus Notes, Apple Computer’s AOCE, Oracle Secure SQL, Internet Explorer, Netscape e Adobe Acrobat.
Sete anos depois, surge numa mailing list dedicada à criptografia (Cypherpunks) código alegadamente equivalente ao RC4. Utilizadores com cópias legais puderam confirmar a compatibilidade. É de realçar, no entanto, que esta não é a implementação comercial, e, como tal, é habitualmente referida como ARC4 (Alleged RC4).
As transformações neste algoritmo são lineares, não são necessários cálculos complexos, já que o sistema funciona basicamente por permutações e somas de valores inteiros, o que torna este algoritmo muito simples e rápido.
De uma forma geral, o algoritmo consiste em utilizar um array que a cada utilização tem os seus valores permutados, e misturados com a chave, o que provoca que seja muito dependente desta. Esta chave, utilizada na inicialização do array, pode ter até 256 bytes (2048 bits), embora o algoritmo seja mais eficiente quando é menor, pois a perturbação aleatória induzida no array é superior.

## Algoritmo
### KSA

O algoritmo key-scheduling é usado para inicializar a permutação no array S. K.Length é definido como o número de bytes na chave e pode variar entre 1 e 256, tipicamente entre 5 e 16 correspondendo ao tamanho de chave de 40-128 bits. Primeiro, o array S é inicializado de tamanho 256. Na primeira repetição:
* O array S é preenchido com os valores de 0 à 255.
Na segunda repetição:
* É somado o valor de j, o valor de S apontado por i e o valor de K (chave) apontado por i e armazenado na variável j.
* Troca os valores entre S[i] e S[j].

#### C#
### PRGA

Para todas repetições necessárias, o PRGA modifica o estado e a saída do byte resultante. Em cada repetição:
* O PRGA incrementa em 1 a variável i.
* Adiciona o valor de S apontado por i com j e armazena o resultado em j.
* Troca os valores entre S[i] e S[j].
* A saída é então calculada fazendo-se a operação XOR (ver em Lógica binária) entre o valor de S apontado por S[i] + S[j] e a mensagem original apontado por k.

#### C#
## Exemplo

Considere a mensagem input = "Texto", convertido em bytes (ver Ascii), input = { 84, 101, 120, 116, 111 }.
Adoptemos a chave K = "chave", que convertido em bytes, K = { 99, 104, 97, 118, 101 }.
Em cada repetição:
| k = 0 i = (i + 1) % 256; i = 1 j = (j + S[i]) % 256; j = (0 + S[1]) % 256 j = 229 Swap(ref S[i], ref S[j]); S[229] = 204 S[1] = 229 result[k] = (byte)(S[(S[i] + S[j]) % 256] ^ input[k]); result[0] = S[(229 + 204) % 256] ^ 84 result[0] = S[177] ^ 84 result[0] = 104 ^ 84 result[0] = 60 | k = 1 i = (i + 1) % 256; i = 2 j = (j + S[i]) % 256; j = (229 + S[2]) % 256 j = 20 Swap(ref S[i], ref S[j]); S[20] = 68 S[2] = 47 result[k] = (byte)(S[(S[i] + S[j]) % 256] ^ input[k]); result[1] = S[(47 + 68) % 256] ^ 101 result[1] = S[115] ^ 101 result[1] = 125 ^ 101 result[1] = 24 | k = 2 i = (i + 1) % 256; i = 3 j = (j + S[i]) % 256; j = (20 + S[3]) % 256 j = 188 Swap(ref S[i], ref S[j]); S[188] = 92 S[3] = 168 result[k] = (byte)(S[(S[i] + S[j]) % 256] ^ input[k]); result[2] = S[(168 + 92) % 256] ^ 120 result[2] = S[4] ^ 120 result[2] = 17 ^ 120 result[2] = 105 |
| k = 3 i = (i + 1) % 256; i = 4 j = (j + S[i]) % 256; j = (188 + S[4]) % 256 j = 205 Swap(ref S[i], ref S[j]); S[205] = 42 S[4] = 17 result[k] = (byte)(S[(S[i] + S[j]) % 256] ^ input[k]); result[3] = S[(17 + 42) % 256] ^ 116 result[3] = S[59] ^ 116 result[3] = 160 ^ 116 result[3] = 212 | k = 4 i = (i + 1) % 256; i = 5 j = (j + S[i]) % 256; j = (205 + S[5]) % 256 j = 70 Swap(ref S[i], ref S[j]); S[70] = 153 S[5] = 121 result[k] = (byte)(S[(S[i] + S[j]) % 256] ^ input[k]); result[4] = S[(121 + 153) % 256] ^ 111 result[4] = S[18] ^ 111 result[4] = 85 ^ 111 result[4] = 58 |
Ou seja, o texto cifrado result = { 60, 24, 105, 212, 58 }. Aplicando o mesmo algoritmo em result, com a mesma chave consegue-se recuperar a mensagem original input.

### Implementação em C
## Segurança

Ao contrário de muitas cifras de fluxo modernas, o RC4 não leva junto um nonce, que é essencial para uma cifra de fluxo, pois reutilizar a mesma chave pode resultar em um ataque de cifra de fluxo. Para evitar isso, implementações que utilizem do algoritmo devem juntar um nonce com a chave de alguma forma. Uma das maneiras de fazer isso seria utilizar um hash na chave e no nonce para gerar uma chave "fresquinha". Porém, muitas implementações simplesmente agregam o nonce junto com a chave; o KSA fraco do RC4 então dá a chance para ataques de chave relacionada, como o ataque Fluhrer, Mantin e Shamir (que é famoso por quebrar o padrão WEP). Uma solução para isso poderia ser utilizar um hash (como era feito com o SSL/TLS) ou simplesmente descartar os primeiros bytes do fluxo de chave. Um algoritmo modificado desse jeito é chamado de "RC4-drop[n]", onde n seria o número de bytes descartados da parte inicial do fluxo de chave.
Em 2013, um grupo de pesquisadores em segurança em Royal Holloway, Universidade de Londres, comunicaram um ataque que pode se efetivar interceptando apenas 2$^{24}$ conexões. Embora não seja um ataque prático para boa parte dos propósitos, este resultado é suficiente para tornar plausível que algum órgão criptológico governamental já pode ter ataques melhores que tornem o RC4 inseguro.. Considerando que em 2013 uma grande quantidade de tráfego TLS usa RC4 para evitar ataques recentes em ciframento em blocos pelo modo CBC, caso estes ataques hipotéticos existam, a combinação de TLS com RC4 torna-se insegura num grande número de cenários práticos. Isso resultou na proibição da utilização do RC4 no TLS pelo RFC 7465.