sábado, 9 de junho de 2007

Reflections on Trusting Trust: Uma Visão baseada em Software Livre

[THOMPSON, 1995] em sua publicação clássica apresenta uma constatação bastante incômoda. Ele trata da confiabilidade de códigos não produzidos localmente ou que não exista a possibilidade de verificação de seu código.

Essa discussão é bastante atual, pois a eterna luta entre a comunidade de software livre e proprietários tem suas raízes baseadas no dilema de como é possível confiar que um software faz exatamente o que se pede, quando não se pode auditar o código.

No Brasil, com a ascensão do Presidente Luiz Inácio Lula da Silva, foi determinado que no âmbito do governo federal softwares de código aberto deviam preferencialmente ser usados. Dentro do contexto de segurança, tal decisão foi extremamente acertada, porém o simples fato de se ter acesso ao software, não é garantia de que o usuário está livre de vulnerabilidades e da ocorrência de falhas de segurança.

Conforme [NIST, 2002] a segurança é um processo onde o fator humano é determinante para seu sucesso. Entre esses fatores pode-se citar como crítico as falhas causadas por usuários internos. Estudos rescentes [MÓDULO, 2003] mostram que um grande número de incidentes de segurança são causados por ações não intencionais de usuários, ou seja, erros ou falhas inseridas pelos próprios funcionários devido ao não conhecimento do sistema usado ou simples falta de disciplina e conscientização no que tange a segurança.

Apesar de a ação de coibir o uso de software proprietário ter sido correta, a forma como o trabalho foi feito apresenta sérias falhas gerenciais. A primeira delas foi a publicidade a migração. Sabe-se que o homem é muito reativo a mudanças, dessa forma uma mudança de seus hábitos diários, se não for devidamente justificada, fará com que ele seja um adversário potencial a idéia. O problema nasce que muitos usuários até hoje não vêem como necessária a migração das aplicações para código aberto, normalmente justicando sua ação em um ponto muito importante: a migração atende apenas aspectos financeiros, sem analisar aspectos produtivos.

Essa visão do problema, apesar de ser bastante simplista, não está equivocada, pois a bandeira levantada pelo Governo Federal em muitas esferas técnicas e gerenciais, apesar de todo a bandeira libertária, foi a que o uso do software livre é bom porque é mais barato que o software proprietário.

Isso não é uma verdade universal, pois os custos mudam de local. O uso de software livre, por ser mais flexível, necessita que seus administradores sejam mais flexíveis também, o que ocasiona que o custo de aquisição seja diluído nos custos de suporte técnico e treinamento. Esse fato não é um problema, pois ao invés de pagar royalts para uma empresa, muitas vezes estrangeira, o dinheiro é gasto no país, aquecendo dessa forma a economia local. Apesar dessa constatação, o que se viu nas repartições públicas não foi essa transferência de dinheiro, mas sim o simples corte de gastos.

A maior vantagem do uso de software livre é a capacidade que dá ao usuário de ter o exato conhecimento do código que está usando. Para isso deve ter conhecimento técnico suficiente para que possa analisar os diversos fontes gerados e verificar que não existem backdoors nem falhas graves de segurança. Porém esse nível de uso do software livre é bastante complicado de ser atingido, pois envolve um conhecimento técnico muito aprofundado, o que muitos órgãos governamentais não estão interessados em pagar.

Uma forma de resolver essa questão seria adotar um modelo similar ao americano, onde alguma entidade seria responsável por auditar todos os códigos utilizados pelo Governo Federal e gerar recomendações e documentos oficiais atestando a segurança da aplicação, ou seja, a não presença de bugs significativos ou cavalos de tróia.

Para que isso fosse possível, seria necessário que houvesse uma padronização dos softwares a serem usados pelas diversas entidades governamentais, o que de certa forma já é feito, pois liberdade não pode significar falta de produtividade.

Porém essa realidade está longe de estar presente. Nossas ações gerenciais e políticas no uso de software livre seja no nível de Política de Estado ou dentro das políticas locais das Instituições, ainda vêem a questão como uma mera questào financeira.

Outro fato que colaboraria para essa questão é que comunidades de software livre muito conhecidas na verdade possuem poucos profissionais com real conhecimento do código fonte que representam. Na maior parte das instituições públicas, a grande parte dos usuários são apenas administradores de sistemas, onde os desenvolvedores de aplicações usam as bibliotecas, linguagens e adaptam o código livre a suas necessidade, não havendo tradição de existirem grandes mantenedores de software básico como compiladores e sistemas operacionais. No Brasil a situação é um pouco melhor, mas não muito diferente.

Essa situação é alarmante, pois a linha de adoção do software livre usada pelo Governo Brasileiro, não resolve o problema do software proprietário, mas sim apenas mascara a questão, pois a visibilidade prometida pelo uso de software aberto está longe de ser alcançada.

Conforme comentado anteriormente, essa questão somente será resolvida quando as autoridades governamentais mudarem sua postura com relação a questão, usando como justificativa para a sua adoção os motivos que permearam o crescimento inicial da comunidade.

Referências Bibliográficas:

[THOMPSON, 1995] Ken Thompson. Reflections oon Trusting Trust. ACM, 1995.

[NIST, 2002] Risk Management Guide for Information Technology System. NIST, 2002.

[MODULO, 2003] 9a. Pesquisa Nacional de Segurança da Informação. Módulo, 2003.

segunda-feira, 4 de junho de 2007

RSA e Testes de Primalidade

1. O Algoritmo RSA

Em 1977, três pesquisadores (Rivest, Shamir e Adleman) desenvolveram um algoritmo de criptografia de chave pública baseado na dificuldade de fatorar números compostos com elevada magnitude, que foi chamado RSA.

O RSA veio a ser o primeiro modelo real, uma vez que o modelo original desenvolvido por Diffie-Helman não tinha viabilidade prática na época.

Segundo o RSA, um usuário inicial (Bob) escolhe dois primos aleatórios de grande magnitude (p e q). Ele multiplica esses valores e gera um novo número n=p*q.

De posse de n, Bob seleciona um expoente criptográfico e, tal que ele tenha a seguinte propriedade gcd (e, (p-1)(q-1)=1.

Após calcular o expoente criptográfico, Bob envia ele (e) juntamente com n para os usuários que deseja estabelecer um canal seguro.

O usuário remoto que deseja enviar uma mensagem (m) através de um canal seguro deve realizar a seguinte operação: c deve ser congruente a me (mod n), onde c é a mensagem cifrada a ser trafegada.

Ao receber a mensagem, Bob deverá calcular um valor d (secreto), tal que d*e seja congruente a 1 (mod(p-1)(q-1)), onde a mensagem em claro (m ) será congruente a cd(mod n).

2. Testes de Primalidade

Conforme pode-se ver nos parágrafos anteriores, a eficácia de uma algoritmo RSA se deve a correta seleção dos valores primos que comporão o valor de n, usado para calcular a chave pública e privada usada pelo algoritmo.

Uma das tarefas assessórias, porém tão importante como o armazenamento de forma segura dos valores p e q, são os testes que definem se um valor é primo ou não, pois caso não o seja, toda a proteção do RSA fica comprometida, pois é possível fatorar o valor de forma bastante eficiente e rápida.

2.1. Teste Fundamental de Primalidade

O teste de primalidade mais rudimentar é baseado em um teorema de primalidade. Esse teorema diz que se um valor n inteiro e positivo é composto, então ele possui um divisor primo menor ou igual a raiz quadrada de n.

Por esse teorema, se eu quero descobrir os números primos que compõe um valor n, então eu texto (força bruta) todos os valores ímpar menores que a raiz quadrada de n para verificar se dividem n.

O problema dessa abordagem é que seriam necessárias pelo menos raiz quadrada de logaritmo da raiz quadrada de n divisões para provar que um valor é primo, ou seja, é extremamente ineficiente.

2.1. Teste Fermat

O teste de fermat diz que se n é primo, para todo a pertencente ao conjunto dos inteiros existe an-1 congruente a 1 (mod n).

Caso o valor n passe em seu teste, ou seja, ele é congruente a 1, não se pode afirmar que o valor é primo, apenas diz-se que ele é provavelmente primo, uma vez que existem alguns números compostos que passam por esse teste (números de Carmichael).

Porém quando o valor de n não passa no teste, pode-se afirmar que o valor n não é primo, ou seja, é composto.

Ex.: n=341=11 * 31 => 2340 congruente a 1 (mod 341), porém 3340 é congruente a 56 (mod 341).

Um bom uso para o teste de fermat é em um teste inicial de um valor, caso ele não passe, automaticamente se define que o número é composto. Caso ele passe, deve-se executar um novo teste que será visto a seguir (o teste de Miller-Rabin).

2.2. Número de Carmichael

Um número de Carmichael é um valor que não se consegue provar pelo teste de fermat se ele é composto ou não para qualquer que seja a base utilizada.

Um exemplo de um número de Carmichael é 561, que é igual 3*11*17 e qualquer que seja a base testada, sempre retornará que o valor é primo.

2.3. Testes de Miller-Rabin

O teste de Miller-Rabin garante que um valor é primo, onde ele é totalmente imune aos números de carmichael.

Para realizar teste de miller-rabin, deve-se escolher um valor ímpar n>1, tal que n-1=m*2k e m também é um valor ímpar.

O teste consiste em selecionar um novo valor randômico a, tal que 1.

Deve-se calcular b0 congruente am (mod n). Se b0 for congruente a +/- 1 (mod n), então n é certamente composto, caso contrário, ele provavelmente seja primo e deve-se calcular um novo valor b1 congruente b02 (mod n).

Caso o valor de b0 for congruente a +/- 1 (mod n), n é composto.

Esse teste deve ser repetido várias vezes de forma a se garantir que o valor n tenha uma grande probabilidade de ser primo, uma vez que o teste miller-rabin é baseado na distribuição estatística de Monte Carlo.

Uma vez que a teoria informa que a densidade de números primos é de aproximadamente 1/ln(x). Se eu quero um x com uma grandeza aproximadamente de 100 casas decimais (x=10100), então a densidade de primos (k) é de aproximadamente 1/230. Como os primos são sempre ímpar (exceto 2), k será aproximadamente 1/100, fazendo com que seja necessário, para essa magnitude, cerca de 100 testes de miller-rabin.

sábado, 28 de abril de 2007

Considerações sobre a Família de Algoritmos SHA-1

Uma das utilidades da criptografia é a garantia da correta identificação dos pares e a integridade das informações trafegadas pelo canal criado. Uma das formas de realizar essas tarefas é através do uso de chaves simétricas associadas a funções de hash.
Por função de entende-se como aquela capaz de receber uma entrada de tamanho variável e gerar um texto com tamanho fixo (fingerprint), que a representa. Desta forma, qualquer alteração no dado de entrada gera um valor diferente de saída, permitindo detectar qualquer adulteração na mensagem de entrada, ou seja, se garante a integridade da mensagem.
Para prover a capacidade de autenticação da mensagem, ou seja a correta identificação dos pares do canal, as funções de hash usam uma chave na composição do fingerprint da mensagem, onde esse tipo particular de função recebe o nome de Message Authentication Code (MAC) [STINSON, 2002].
De forma resumida, para prover apenas a integridade de uma mensagem basta o uso de uma função de hash comum (unkeyed function), porém quando se deseja autenticação associado à integridade, deve-se usar uma função MAC.
As funções MAC são implementadas através de um algoritmo simétrico, onde em um canal seguro estabelecido é usada à chave anteriormente acordada (ou uma variação da mesma) para fins de autenticação e garantia da integridade da mensagem.
Apesar de ser computacionalmente mais eficiente, existem casos onde não existe um segredo compartilhado entre os pares. Nesses casos só resta o uso assinaturas digitais calculadas através de algoritmos assimétricos. Porém devido a sua ineficiência, o uso desses algoritmos em segmentos de dados muito grandes não é recomendado. Isso faz com que sejam usadas funções de hash sobre a mensagem e a assinatura assimétrica é aplicada somente sobre o fragmento comprimido e não sobre a mensagem inteira, agilizando o processo.
Uma das funções mais utilizadas para prover integridade é o SHA-1, enquanto quando deseja-se autenticação associada, usa-se o HMAC-SHA-1. Esses algoritmos pertencem a uma família de algoritmos desenvolvidos pela National Security Agency (NSA), tendo a sua divulgação realizada em 1995.
A família SHA-1 produz uma mensagem autenticada de 160 bits e tem como entrada uma mensagem de tamanho variável (máximo de 264 bits) e uma chave de 80 bits.
Apesar de estar em uso bastante intenso atualmente e previsto como protocolo de autenticação padrão para vários protocolos em uso na Internet, existem vários estudos comprovando a sua fragilidade.
Um ataque descrito por [WANG, 2005] apresentou que foram encontradas colisões no algoritmo após apenas 269 interações, onde o trabalho de quebra do mesmo por força bruta é da ordem de 280 operações. Para realizar ataques foi necessário técnicas analíticas avançadas, porém diferentemente de ataques anteriores, que demonstravam fragilidades em versões simplificadas do algoritmo, esse foi demonstrado na versão integral do mesmo.
Porém um grande problema apontado por esse estudo é a fragilidade encontrada nas assinaturas digitais, pois conforme comentado anteriormente, devido a critérios de eficiência, o algoritmo assimétrico não é usado em toda mensagem, mas apenas sobre um fingerprint gerado através de uma função MAC.
Mesmo assim, o NIST anunciou que pretende usar o protocolo até 2010 [NIST, 2004], quando deve o substituir pela sua versão mais moderna, o HMAC-SHA2.


Referências Bibliográficas:

[STINSON, 2002] Stinson, D.R. Cryptography – Theory and Practice, 2nd Edition. Chapman & Hall/CRC, 2002.

[NIST, 2004] NIST Brief Comments on Recent Cryptanalytic Attacks on Secure Hashing Functions andthe Continued Security Provided by SHA-1H. Disponível em: http://csrc.nist.gov/hash_standards_comments.pdf. Acessado em 27 de setembro de 2006.

[WANG, 2005] Wang, X., Yin Y.L. and Yu H. Finding Collisions in the Full SHA-1. CRYPTO 2005. Disponível em: http://www.infosec.sdu.edu.cn/paper/sha1-crypto-auth-new-2-yao.pdf. Acessado em 27 de abril de 2007.

quinta-feira, 29 de março de 2007

A quebra do Enigma - Um ensinamento sobre o papel do homem para a proteção de ambientes computacionais.

Com a migração dos negócios realizados para o ambiente digital, a criptografia passa a ser cada vez mais um fator crítico para o sucesso das empresas.
Em determinados segmentos, devido a natureza do negócio, esse fato sempre foi uma realidade. Pode-se citar como exemplo, a área de defesa, cujo o tipo de negócio requer que as informações geradas tenham que ser corretamente identificada e protegida, pois no caso de serem corrompidas ou descobertas podem gerar prejuízos materiais e humanos irreversíveis.
O uso da criptografia para fins militares remota da antiguidade, quando César usava para seus generais em batalha um mensagem cifrada usando um mecanismo de deslocamento alfabético. O método era bastante rudimentar e consistia no deslocamento do alfabeto de um valor de n posições. Por exemplo se o alfabeto sofre um deslocamento de duas posições, o texto "casa" passa a ser escrito como "ecuc".
Uma evolução desse mecanismo consiste na substituição mono-alfabética, onde em vez de deslocar o alfabeto em um número "x" de posições, na verdade se cria um novo alfabeto, onde cada letra do alfabeto é colocada em uma posição nova, onde não há qualquer co-relação entre a posição da letra no alfabeto cifrado e a sua posição no alfabeto real.
Ambos os mecanismos de cifragem sofrem um problema crítico para seu sucesso, pois basta que se identifique o idioma no qual a mensagem foi escrita para ser possível regenerar a mensagem através de uma análise probabilística da mesma.
Para solucionar essa dificuldade foi desenvolvido os sistemas poli-alfabéticos, que consiste de um algoritmo na qual a chave define qual será o alfabeto utilizado no processo de cifragem. Apesar desse esquema de cifragem possuir algoritmos conhecidos de decifragem, caso seja usado uma chave muito grande e outros artifícios que compliquem o processo de decifragem da mensagem, ele até os dias atuais continua muito difícil de quebrar.
Durante a Segunda Guerra, os alemães consigiram extremas vantagens nos campos de batalhas utilizando uma máquina chamada enigma, que implementava um algoritmo de cifragem baseado em um mecanismo poli-alfabético.
Esse mecanismo mostrou-se extremamente eficiente, fazendo com que os aliados tivessem que empreender um esforço considerável para conseguir quebrá-lo.
Porém, assim como em muitos ataques atuais, esse trabalho, apesar de ter sido realizado graças ao uso de modernas técnicas de cripto-análise, teve como fator crucial para o sucesso, o mal uso do sistema pelos usuários.
Relatos históricos apresentam que o grupo de cripto-análise dos aliados utilizavam de algumas fragilidades operacionais empreendidas pelos alemães ao sistema.
Uma dessas vulnerabilidades consistia de que mensagens metereológicas eram transmitidas pelo enigma. Já que essa informação era de conhecimento dos aliados, pois eles também operavam no mesmo teatro de operação, ficava mais simples de conseguir obter a chave utilizada para cifrar o texto.
Outro erro de operação é encontrado na maior parte de quebra de chaves da atualidade, o uso de chaves fracas pelos operadores das máquinas, chaves essas como iniciais de namoradas, nomes familiares ou até mesmo a mesma chave sempre. Os aliados sabendo qual o usuário que operava o enigma, já tinha de antemão a chave utilizada pelo sistema.
Atualmente os algoritmos criptográficos não utilizam mecanismos de substituição alfabética, mas sim técnicas matemáticas para realizar o processo de proteção de uma mensagem, o que por si só é mais seguro e eficiente. Porém, assim como no caso apresentado nessa nota, caso o sistema não seja operado devidamente, ele fracassará em seu objetivo.
Por exemplo, no caso do uso de um sistema assimétrico de nada adianta gerar chaves usando geradores de números pseudo-aleatórios robustos se essas chaves são armazenadas em claro no disco rígido do usuário sem qualquer controle de acesso ao repositório onde ela se encontra.
Dessa forma, para proteger um negócio, além de usar um sistema de segurança robusto, deve-se antecipadamente pensar no fator humano, criando um ambiente no qual a tecnologia seja adequadamente utilizada, minimizando os erros não propositais, que conforme rescentes pesquisas são os maiores provocadores de incidentes de segurança.

sexta-feira, 23 de março de 2007

Taxonomia de Segurança

Essa semana foi analisado um artigo bastante antigo (1994) que tratava da classificação das diversas falhas de segurança.

A taxonomia de um sistema é importante pois permite definir fronteiras claras e bem definidas para o mesmo, ocasionando que seja possível analisar em detalhes as diversas fronteiras que o compõe.

Apesar de sua idade, o trabalho de [Landwehr et all] ainda é bastante válido para ser possível entender dois aspectos importantes: problemas de segurança computacional não são atuais e sua natureza, em grande maioria, são pouco mutáveis.

É claro que existem novas classes e falhas de segurança que não são contempladas pelo estudo referenciado acima, mas de uma forma geral, esses novos problemas são apenas adaptações e/ou evoluções dos existentes no estudo.

Um aspecto forte no documento é sua análise sobre como as falhas podem ser inseridas, acidentalmente ou propositadamente, durante o ciclo de vida do desenvolvimento de um produto. Isso é importante pois quando a segurança é analisada através desse enfoque, está na verdade procurando-se prevenir a ocorrência de falhas e não remediar, como é o enfoque da maior parte dos artigos encontrados na área. Como exemplo pode-se citar que quando se adquire um sistema de detecção de intrusos está se combatendo o resultado de uma falha, enquanto se investe em gestão de segurança durante o ciclo de desenvolvimento, está se prevenindo falhas.

Outra parte interessante do estudo são os exemplos apresentados ao final do documento, dando a um leitor não familiarizado com a área de segurança uma forma de entender a taxonomia sugerida.

[Landwer et all] A Taxonomy of Computer Program Security Flaws with Examples. Publicado na ACM Computing Surveys no. 26 em Setembro de 1994.

quinta-feira, 8 de março de 2007

Divulgação da Fraude do Sumitomo Bank

No ano de 2005 foi divulgado uma tentativa frustrada de fraude no banco japonês Sumitomo. A fraude consistia no roubo de senhas de funcionários chaves do referido banco através de um dispositivo de keylogging (espécie de guardador de senhas) implementado em hardware.
A importância da notícia não foi a tentativa da fraude em si, mas sim, o fato de ter sido amplamente divulgado, fato muito raro quando envolve Instituições bancárias.
Outro fato bastante interessante sobre o ocorrido é a simplicidade do ataque, pois ele poderia ser empreendido remotamente via algum tipo de malware embutido em arquivos legítimos do usuário (apresentações, e-mails, entre outros).
Desse incidente dois grandes insinamentos podem ser tirados. O primeiro deles é que as empresas devem repensar a divulgação de incidentes de segurança pois um dos pilares da segurança da informação é a negação a segurança por obscuridade, ensinamento que a muito a criptografia usa para validar seus algoritmos de forma mais eficiente.
Caso as empresas divulgassem mais os seus incidentes de segurança, o ensinamento poderia ser aprendido, além de que daria uma real dimensão do problema para as autoridades e, muito provavelmente, ações concretas internacionais já deveriam ser tomadas.
O segundo ensinamento diz respeito ao planejamento de segurança das empresas. Um banco é uma instituição que possui um investimento bastante significativo em soluções de segurança da informação. Porém o combate a ameaças virtuais é algo bastante dinâmico e por maior que seja o investimento na área, nunca será o suficiente para erradicar esse problema.
No caso do banco Sumitomo, talvez se houvesse uma maior preocupação na educação e controle dos seus funcionários, talvez esse problema não tivesse ganhado dimensões tão grandes. Esse esquema de conscientização já é adotado com sucesso em outras áreas da segurança (safety), como a do trabalho e a de vôo.
Caso os funcionários fossem constantemente alertados quanto ao perigo de guarda senhas de forma local a sua máquina, de tomar cuidado ao abrir determinados conteúdos e de sempre modificar suas senhas, problemas similares a esses, que ocorrem diariamente mas não são divulgados, seriam muito menos comum.