Um Manifesto!

...

  • Increase font size
  • Default font size
  • Decrease font size

Blog

Troca de mensagens com criptografia em Java, usando AES.

E-mail Print PDF
O escopo de uma aplicação incluía a troca de mensagens sensíveis como parte de um WebService, e além do uso de HTTPS, deveria ser usada alguma forma de criptografia na parte crítica do serviço.

Logo deveria haver uma forma de criptografia disponível tanto no servidor como nos clientes, inicialmente um serviço em Java e o cliente seria no Android (depois outros surgiriam), com isso tem quer ser usado um algorítimo de chave simétrica, que permitisse recuperar a mensagem original de posse da chave de criptografia usada. Obviamente deveria ser um mecanismo eficiente.

Escolhi o AES por acreditar ser o padrão ideal atualmente, "lançado" em 2001 entrou em estudo pelo governo dos EUA e hoje é o seu padrão para troca de documentos, incluindo os "tops". Usando mesmo uma chave de apenas 128bits seria extremamente seguro, a chave pode ser de 128bits, 192bits ou 256bits.

Se você está desenvolvendo em Java EE 5 ou no Android (Ou qualquer Java 6, acredito eu, mas não confirmei), ambos já possuem a implementação deste algoritmo, caso a plataforma não possua você pode usar a implementação do Bouncy Castle, geralmente basta o Provider do bcprov-jdk16-*.jar .

O primeiro passo para a criptografia é definir uma chave, ela pode ser gerada automaticamente pelos mecanismos do sistema:

public byte[] key() throws NoSuchAlgorithmException {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
SecretKey key = keyGen.generateKey();
return key.getEncoded();
}

Esse método retorna o array de bytes de uma chave de 128bits, podemos usar 256bits mas esse algorismo nem sempre está disponível ou requer configurações especificas do JRE.

A criptografia trabalha com valores em Hexadecimal, assim a chave também usa valores em hexa, você pode criar uma chave com um array de hexas do tamanho que deseja da chave, uma chave de 128bits são 8 bytes (128/16), assim:

byte[] key = { 0x0f, 0xad, 0x54, 0x12, 0x00, 0xaf , 0x34, 0xff }

Em posse de uma chave de criptografia basta aplica-la a uma engine de criptografia, junto dos bytes da mensagem a ser encriptada, com o seguinte método:

public byte[] encode(byte[] input, byte[] key) throws NoSuchAlgorithmException, 
InvalidKeyException, IllegalBlockSizeException,
BadPaddingException, NoSuchPaddingException {
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(input);
return encrypted;
}

Detalhe para o "AES/ECB/NoPadding" , isso usa o algoritmo AES e não faz o padding da mensagem.

Por trabalhar em hexadecimal, o algoritmo trabalha com blocos de 16 bytes, então a mensagem(seus bytes) devem ter uma tamanho múltiplo de 16 para não haver erros de "BadPaddingException: pad block corrupted, para isso podemos usar os seguintes métodos, que preenchem os espaços que faltam até formar o tamanho necessário com "null":

public String nullPadString(String original) {
StringBuffer output = new StringBuffer(original);
int remain = output.length() % 16;
if (remain != 0) {
remain = 16 - remain;
for (int i = 0; i < remain; i++) {
output.append((char) 0);
}
}
return output.toString();
}

Então podemos encriptar uma mensagem assim:

String mensagem = "Hello World!";
byte[] enc = encode(nullPadString(mensagem).getBytes(), key);

Para descriptografar a mensagem não tem mistério, basta o seguinte método:

public byte[] decode(byte[] input, byte[] key) throws NoSuchAlgorithmException, 
InvalidKeyException, IllegalBlockSizeException,
BadPaddingException, NoSuchPaddingException {
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(input);
return decrypted;
}

A única diferença é o parâmetro passado ao Cipher, para de descriptografar.

Agora que podemos criptografar e decodificar as mensagens, precisamos garantir seu formato ao ser enviado via HTTP/HTTPS.

Novamente, como trabalhamos com Hexadecimal, ele não é simplesmente convertido para String, não sem perda, e a conversão de volta também traria riscos, ainda mais se for em plataformas diferentes.

Precisa-se então converter esses valores hexadecimais para uma representação "por extenso" destes, e que possa ser transformado de volta, e podemos alcançar isto com os seguintes métodos:

public String fromHex(byte[] hex) {
StringBuffer sb = new StringBuffer();
for (int i=0; i < hex.length; i++) {
sb.append( Integer.toString( ( hex[i] & 0xff ) + 0x100, 16).substring( 1 ) );
}
return sb.toString();
}

public byte[] toHex(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}

Então para enviar uma mensagem podemos proceder da seguinte forma (contando que ambos possuem a mesma chave):

String mensagem = "Hello World!";
byte[] enc = encode(nullPadString(mensagem).getBytes(), key);
String msgParaEnviar = fromHex(enc);

Enviamos então via http a string msgParaEnviar, e ao recebe-la procedemos a decodificação:

byte[] msgEnc = toHex(msgRecebida);
byte[] msg = decode(msgEnc,key);
String mensagem = new String(msg).trim();

Assim temos a mensagem nas duas pontas, o trim é necessário devido ao "padding".

Veja o código da Classe de Criptografia que uso.

Last Updated on Monday, 14 December 2009 01:32
 

PHPDocumentor: Documentação de API em PHP

E-mail Print PDF

Outra parte importante em um projeto, principalmente se está tratando de pacotes públicos e frameworks, é uma documentação completa. Mas documentar é um saco.

Parte da documentação incluí a API de classes, com os pacotes, classes, métodos e suas descrições. O padrão para documentação destes são o docblocks, ou phpdoc, que são comentários no código, sobre a classe, propriedade ou método, e possuem descrição e tags padrões para completar a documentação.

< ?php

/**
* Class Foo
*
* This class implements a hello speaker
* @package hello
*/
class Foo {
/**
* this is some useless var
*/
private $bar ;

/**
* Says hello to provided name
* @param string $name this is the name to be said
* @return Foo
*/
public function hello($name="world") {
echo "Hello, ".ucfirst($name)."!";
return $this
}
}

Esses comentários comuns são mais fáceis de escrever durante o desenvolvimento, e acrescentam muito a documentação. O padrão permite descriçoes muito mais complexas que isso, mas na maior parte das vezes não é necessário.

Agora que esses comentários estão em seu lugar basta usar uma ferramenta para transformar o código em documentação de verdade, pronto para ir online e estar disponível para consulta.

O PhpDocumentor é extremamente fácil de usar e instalar, e gera documentações razoáveis. Ele possui bastante opções de formato de saída (html, pdf, xml...) e templates, mas vou fazer só o básico aqui.

Para instalar o PhpDocumentor você pode usar o PEAR ( se você não conhece, está perdendo muito), basta rodar o comando a seguir:

# pear install PhpDocumentor

Se tudo correr bem você pode agora transformar seu código em documentação com a linha a seguir:

$ phpdoc -t docs -o HTML:default:eathli -d src

Nesse caso a documentação será salva na pasta docs, no formato HTML usando o template earthli, através dos arquivos da pasta src.

Basta apontar seu navegador para a pasta docs e navegar na documentação agora.

 

Documentação em PHP
 

 

Confira mais opções comentários, anotações e tudo mais no Manual do PhpDocumentor.

Last Updated on Wednesday, 02 December 2009 12:18
 

Testes Unitários em PHP com simpletest

E-mail Print PDF

Testes automatizados são parte importante do desenvolvimento de software, apesar de ser a mais demorada prática a se aceitar, é a que mais traz benefícios. O seu uso deve ser simples, e por isso é bom o uso de um framework prático para tal.

No começo escrevi scripts de testes "na mão" mesmo, com ifs e elses, mas, apesar de ser melhor que nada, não é nada prático se comparado ao uso de um bom framework. Então tentei usar o phpunit uma vez, mas achei mais complexo que o necessário, então parti para o simpletest.

O simpletest é realmente simples, basta fazer o download do pacote e descompacta-lo na sua pasta de testes, e em seguida é só escrever sua suite de testes.

Uma suite de testes é escrita da seguinte forma:


< ?php

include_once 'simplestest/autorun.php';

class AllTests extends TestSuite {
function allTests() {
$this->TestSuite("Meus testes");
$this->addTestCase(new MeuCasoDeTests1);
$this->addTestCase(new MeuCasoDeTests2);
}
}

?>

E cada caso de teste se define da sequinte forma:


< ?php

include_once 'simpletest/autorun.php';

class MeuCasoDeTests1 extends UnitTestCase {
function testFoo() {
$this->assertEqual("foo","foo");
}
function testBar() {
$this->assertEqual("foo","bar");
}
}
?>

Cada função no caso de teste iniciada por "test" será executada na ordem declarada, e o cada "assert" é um teste. Existem vários "asserts" disponíveis.

Basta acessar pelo browser a url do caso de testes ou da suite de testes e ter certeza de testar tudo, para garantir a qualidade do software.

Last Updated on Tuesday, 01 December 2009 13:25
 

Programando fora da zona de conforto: Programação Funcional e NoSQL

E-mail Print PDF

Mais alguns links da série de programação funcional, e também adcionar o NoSQL a lista, banco da dados não relacionais para resolver o problema da escalabilidade.

 Divirta-se. 

Last Updated on Sunday, 06 December 2009 13:32
 

Linux em um pendrive: Debian e Enlightenment (E17) persistente.

E-mail Print PDF

História

 

Enlightenment E17
 

 

Além de já ter usado o Linux em um pendrive com o DSL, que é uma das distros que melhor se adaptam ao estilo, é fácil hoje instalar outras distros semelhantes, como o Slax, o SliTaz (muito bom) e o TinyCore(abandonei o DSL por este), com seus 10MBs.

A boa noticia é que hoje é bem mais fácil rodar um linux a partir de um pendrive, temos o projeto pendrive linux, com vários distros preparadas para tal, e o unetbootin para configurar e “bootar” qualquer ISO a partir de um pendrive.

Parti então para as distros completas: Ubuntu e Debian. O Ubuntu eu não gosto, acho um desktop muito fraco. O Debian iniciei com o projeto do Debian Live, oficial, mas este se baseia na versão estável, então está muito antigo nos pacotes. Mas como o debian é o debian era possível reconstruir o Debian live em qualquer versão, com o Debian Live Helper, mas também dava muito trabalho e demorava muito.

Foi ai que pensei em ficar com as minimalistas, entre o TinyCore e o SliTaz. Não fiquei com o SliTaz por que me parecia pacotes muito antigos, em especial o kernel, já o TinyCore eu fiquei com preguiça mesmo, afinal ainda seria muito parecido com o DSL.

Ai eu esbarrei no Elive. Na verdade já paquerava o Enlightenment tem um bom tempo, mas E16 não é tão interessante, e o E17 envolvia muitas gambiarras, e as versão “fáceis” de instalar não estavam muito legais.

Uma boa opção me pareceu usar o Elive, baseado no debian, que já vem configurado com tudo de bom e melhor do Enlightenment de desenvolvimento, por isso resolvi testa-lo.

Como fazer

 

Unetbootin com E17 ELIve
 

 

Primeiro instale o Unetbootin, que está presente na maioria das distribuições modernas:

# aptitude install unetbootin

Executando-o como root, o unetbootin já existem diversas distros prontas, ele mesmo se encarrega de baixar a ISO configurar o pendrive e torná-lo bootável com o syslinux.

Você pode também fazer o Download da ISO do ELive você mesmo(eu fiz assim), e seleciona-la no unetbootin, e então é só seguir e iniciar o processo, não tem mistério nenhum.

O passo seguinte, após o unetbootin dizer que terminou, é configurar um arquivo para que o Elive salve as alterações. Você precisa primeiro criar um arquivo para ser a “partição” da persistencia:

# dd if=/dev/zero of=elive-rw bs=1M count=1024

O valor do count diz o tamanho do arquivo em megabytes, veja quanto resta no pendrive e quanto você quer usar, no exemplo vai ter 1GB (mais ou menos).

Em seguida formate-o como ext3, apenas confirme:

# mkfs.ext3 elive-rw

Agora pode copiar o arquivo elive-rw para a raiz do pendrive, e editar o arquivo de boot “syslinux.cfg” nessa mesma raiz. No linha append da entrada padrão adcione “persistent=elive-rw” e salve.

Basta desmontar o pendrive e rebootar o computador com a BIOS configurada para carregar apartir do pendrive e curtir no ambiente. Trate-o como um netbook, pois o espaço é pouco.

Um detalhe importante, que me atrapalhou a testar o elive antes, é que ele não roda no Qemu(e KVM) por algum motivo, mas funciona no VirtualBox e VMWare, eu acredito.

Agora posso carregar meu lindo ambiente de programação para todo canto, combinado com controle de versão, e impressionar todo mundo com como o linux pode ser bonito :D

Last Updated on Saturday, 21 November 2009 19:50
 

Compartilhando internet pela rede sem fio no linux

E-mail Print PDF
Tutorial de como configurar sua placa de rede sem fio para compartilhar a internet, no linux.

Aqui vou explicar como configurar seu computador/notebook como hotspot wifi, para compartilhar a internet na rede sem fio, com o mínimo de "segurança" WEP apenas.

O Primeiro passo é saber qual a interface que chega a conexão com a internet, no geral se é internet discada, 3G ou se usa o pppoe a interface é ppp0, se a internet chega roteada pela rede é a mesma da interface de rede, eth0 ou outro. Aqui uso internet móvel 3G, então conecta em ppp0.

Temos então que mascarar o encaminhamento de pacotes dessa interface por um nat, usando as regras do iptables. Carregue o módulo de nat, definir a regra e ativar o encaminhamento no sistema, com os seguintes comandos:

# modprobe iptable_nat
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
# echo 1 > /proc/sys/net/ipv4/ip_forward

O próximo passo é configurar a rede wifi, com os seguintes comandos:

# ifconfig wlan0 down
# ifconfig wlan0 192.168.0.1 netmask 255.255.255.0 broadcast 192.168.0.255
# ifconfig wlan0 up

Em seguida definimos as caracteristicas da rede sem fio, definindo o nome, o modo ad-hoc, a chave de encriptação e para apenas aceitar com encriptação, os comandos:
# iwconfig wlan0 essid "acer"
# iwconfig wlan0 mode ad-hoc
# iwconfig wlan0 key 's:diogo'
# iwconfig wlan0 key restricted

Para os clientes receberem as configurações devidas você precisará agir como cliente dhcp (ou configurar manualmente a rede nos clientes), você pode instalar o servidor com o seguinte comando:

# aptitude install dhcp3-server

Para configurar o servidor, edite o arquivo /etc/dhcp3/dhcpd.conf, conforme:

ddns-update-style ad-hoc;
option domain-name "home.org";
option domain-name-servers 208.67.222.222, 208.67.220.220;
default-lease-time 600;
max-lease-time 7200;
authoritative;
log-facility local7;
subnet 192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.10 192.168.0.254;
option routers 192.168.0.1;
option broadcast-address 192.168.0.255;
}

Com o dhcp configurado, basta ativa-lo na interface da rede sem fio.

# dhcp3d wlan0

Agora os clientes podem se conctar a sua rede e navegar na sua internet. Você pode tentar configurar outro meio mais seguro que WEP, mas eu não sei ainda :P e definir regras no dhcp e iptables limitando os MACs e IPs, mas isso fica para próxima.
 
  • «
  •  Start 
  •  Prev 
  •  1 
  •  2 
  •  3 
  •  4 
  •  5 
  •  6 
  •  7 
  •  8 
  •  9 
  •  10 
  •  Next 
  •  End 
  • »


Page 1 of 19