2009/06/08

Encriptação de dados com AES

Nas últimas semanas tive que ir à net à procura de formas de encriptar dados (byte[], ficheiros) com AES. Como não foi imediato, deixo aqui o código de uma prova de conceito que compus, para o caso de ser útil para mais alguém. A base deste código é uma classe que encripta dados que estão em memória.

A classe, que tem o inspirado nome de AES, pode ser usada da forma seguinte:


// Texto para encriptar
String message = "Isto é um texto para ser encriptado.\n" +
"Tem duas linhas, e esta é a segunda.\n" +
"E afinal tem mais uma... :-)\n";

System.out.println("Original string: " + message);

// Primeira instância da classe, para encriptar
AES genio = new AES();

// Encriptação
byte[] coded = genio.dataEncrypt(message.getBytes());
System.out.println("encrypted string: " +
bytes2hex(coded) +
" - []size=" + coded.length);

// Testa a desencriptação
byte[] decoded = genio.dataDecrypt(coded);
System.out.println("Decrypted string: " +
new String(decoded));

// Pede-lhe a chave...
byte[] key = genio.getKeyEncoded();

// Nova instância da classe, que recebe a chave
AES genio2 = new AES(key);

// Tenta desencriptar de novo, a ver se sai bem
byte[] decoded2 = genio2.dataDecrypt(coded);
System.out.println("Decrypted2 string: " +
new String(decoded2));


Como vêem, é facílimo.

Agora a classe propriamente dita:


import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.*;
import javax.crypto.spec.*;

public class AES {

private KeyGenerator kgen;
private SecretKey skey;
private SecretKeySpec skeySpec;
private Cipher cipher;
private byte[] raw;
byte[] iv = new byte[]{
0x07, 0x00, 0x01, 0x03, 0x00, 0x06, 0x04, 0x03, 0x09, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);

public AES() throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException {

// Get the KeyGenerator
kgen = KeyGenerator.getInstance("AES");
kgen.init(128);

// Generate the secret key specs.
skey = kgen.generateKey();
raw = skey.getEncoded();
skeySpec = new SecretKeySpec(raw, "AES");

// Instantiate the cipher
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

}

public AES(String key) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException {

raw = hex2bytes(key);
skeySpec = new SecretKeySpec(raw, "AES");

// Instantiate the cipher
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

}

public AES(byte[] key) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException {

skeySpec = new SecretKeySpec(key, "AES");

// Instantiate the cipher
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

}

public String stringEncrypt(String message) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException,
InvalidAlgorithmParameterException {
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, paramSpec);
byte[] encrypted = cipher.doFinal(message.getBytes());
return bytes2hex(encrypted);
}

public String stringDecrypt(String code) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException,
InvalidAlgorithmParameterException {
cipher.init(Cipher.DECRYPT_MODE, skeySpec, paramSpec);
byte[] original = cipher.doFinal(hex2bytes(code));
return new String(original);
}

public byte[] dataEncrypt(byte[] data) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException,
InvalidAlgorithmParameterException {
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, paramSpec);
byte[] encrypted = cipher.doFinal(data);
return encrypted;
}

public byte[] dataDecrypt(byte[] code) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException,
InvalidAlgorithmParameterException {
cipher.init(Cipher.DECRYPT_MODE, skeySpec, paramSpec);
byte[] original = cipher.doFinal(code);
return original;
}

public static byte[] hex2bytes(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;
}

public static String bytes2hex(byte buf[]) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;

for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10) {
strbuf.append("0");
}

strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}

return strbuf.toString();
}

public String getKey() {
return bytes2hex(skeySpec.getEncoded());
}

public byte[] getKeyEncoded() {
return skeySpec.getEncoded();
}
}


Num próximo post publico o código necessário para encriptar e desencriptar um ficheiro, guardando a chave noutro.

2008/04/10

Sun SPOT SDK

Podemos, já hoje, obter o SDK (a bancada de software, não o hardware com o kit) do Sun SPOT, bastando para isso enviar um mail para davidgs at sun ponto com, com subject "SDK Beta". O kit podem encomenda-los pelo SUN SPOT World, embora não seja acessível a todos as bolsas, existindo no entanto descontos académicos.

O SUN SPOT, trata-se, de uma forma simplificada, de um "pequeno" dispositivo de comunicação sem fios, implementando a plataforma Java ME, com suporte para CLCDC 1.1 e MIDP 1.0 usando a JVM Squawk

A JVM Squwak corre directamente no hardware, sendo implementados alguns serviços básicos de SO (em C), sendo todo o resto em Java inclusive os próprios devices drivers.

Sun SPOT World
http://www.sunspotworld.com

Sun SPOT no java.net
https://spots.dev.java.net

Squawk VM (a VM usada no Sun SPOT)
https://squawk.dev.java.net

Sun SPOT plugin for NetBeans 6
http://blogs.sun.com/davidgs/entry/netbeans_6_0_and_sun

Pesquisa por Sun SPOT no YouTube
http://www.youtube.com/results?search_query=Sun+SPOT&search_type=

Roger Meike's Blog
http://blogs.sun.com/roger/

Blog SPOT Blog - Beta Starts
http://blogs.sun.com/davidgs/entry/beta_starts

2007/12/06

PT.JUG já tem camisolas


Quem está inscrito no ptjug-geral do Google Groups já sabe. O PT.JUG já tem merchandising à venda numa loja da Spreadshirt. E as primeiras encomendas já foram entregues.

Entre elas estava esta linda camisola com o logo do grupo, que se apresenta acima.

Não deixem de ir à Loja do PT.JUG. Tem de tudo pró menino e prá menina.

2007/11/14

Parâmetros JVM para geração heap dump em situações de falta de memória

De modo a diagnosticarmos situações de OutOfMemory poderá ser útil passar o parâmetro HeapDumpOnOutOfMemoryError à JVM (especialmente interessante em ambientes de produção, mas não só...)

VM Option
Description

-XX:+HeapDumpOnOutOfMemoryError

Dump heap to file when java.lang.OutOfMemoryError is thrown. Manageable. (Introduced in 1.4.2 update 12, 5.0 update 7.)

-XX:HeapDumpPath=./java_pid<pid>.hprof

Path to directory or filename for heap dump. Manageable. (Introduced in 1.4.2 update 12, 5.0 update 7.)

Java HotSpot VM Options
http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp

Os ficheiros de heap podem ser analisados com o jhat
http://java.sun.com/javase/6/docs/technotes/tools/share/jhat.html

HAT - Versões mais antigas do HAT (versões recentes incluidas com Java SE 6 ou superior)
https://hat.dev.java.net/

Algumas outras ferramentas:
JXInsight
http://www.jinspired.com/products/jxinsight/

NetBeans Profiler
http://www.netbeans.org/products/profiler/

Eclipse Test & Performance Tools Platform Project
http://www.eclipse.org/tptp/

2007/10/02

Novo servidor do PT.JUG já chegou

Já chegou o novo servidor que irá suportar a presença web do PT.JUG.


Trata-se de um SunFire X2100, com um processador AMD Opteron e 2GBytes de RAM ECC, gentilmente cedido pela Sun Microsystems.

Neste servidor irá ser instalada a última versão do Ubuntu Server Linux, o Java Runtime Edition 6 e o Liferay CMS/Portal.

2007/08/20

Programadores de Java ganham, em média, mais 20% que os de .Net

Segundo as estatísticas do site de empregos de TI www.itjobswatch.co.uk, os empregos de Java pagam, em média, mais 20% do que os empregos em .Net. Enquanto os primeiros têm uma remuneração média anual de €72.951, os segundos ficam-se pelos €60.155.

Infelizmente, nem tudo são boas notícias. É que a procura de pessoal para trabalhar em .Net subiu 4 lugares no ranking, no último ano, e os empregos em Java desceram 2 lugares no ranking.


2007/08/01

Governação para um grupo alargado no pt-jug

Todas as comunidades, quando atingem uma dimensão tal que torna o diálogo impossível e moroso, precisam de delegar as responsabilidades em menos pessoas. Por enquanto somos poucos mas bons, no futuro, desejo que sejamos muitos. Desejo que esta comunidade Portuguesa de Java tenha como alvo um público o mais alargado possível, de modo a obter massa crítica para ter sucesso sustentado a longo prazo.

Ponderei longa e duramente sobre este assunto para o caso particular do pt-jug.

Penso que quem presidir o pt-jug deve ter experiência associativa, bem como saber profundo sobre comunidades online.

Penso que o modelo do Ditador Benévolo não se aplica aqui. Penso que tal Ditador, para ser um bom ditador, respeitado por todos, tem de ser forjado no combate no terreno. Tal líder, para além disto, tem de se dedicar de corpo e alma.

Ditadores Benévolos, na nossa área das comunidades online, são como o Linus Torvalds, autor do Kernel Linux, que lutou sozinho quando mais ninguém acreditava e arrastou uma multidão atrás. Dedicou toda a sua vida ao projecto. Moldou as decisões pessoais a ele: inclusivé mudou de casa várias vezes, para obter um ambiente mais propício ao trabalho.

Não é o nosso caso para o pt-jug. Penso que não acreditamos em ninguém como capaz de semelhante sacrifício pessoal em prol desta comunidade. Não devemos ficar de braços cruzados à espera de um Afonso Henriques, Dom Sebastião, Marquês de Pombal, ou Salazar vindo do nevoeiro para nos salvar. Temos de nos saber governar sem um ditador benévolo.

Vejo, no seio do pt-jug, pessoas que sabem do que falam. Pessoas motivadas, sem papas na língua, com personalidades fortemente individualistas e agendas próprias. Temos de lhes dar asas e espaço de manobra. Se as encurralarmos, lutam ou fogem, tal como no passado.

Penso que devemos seguir o modelo de governação dos cidadãos livres : Atenas.
Modelo contrário ao de Esparta, cidade militarizada em que cada membro era um soldado com dedicação total à causa.

Não acredito nos modelos mistos das democracias modernas, como a do governo dos EUA, não acredito nestes modelos para o nosso caso.

Penso que os modelos das democracias modernas premeiam a mediocridade para garantir a estabilidade. Penso que este compromisso, a favor da estabilidade, é válido para o governo de uma grande nação, em que a própria segurança física das pessoas está em jogo, mas não penso que o seja no nosso caso.

Na Atenas primordial a liderança era feita por Arcontes. Uma trindade de homens livres.

Porquê três?

Penso que mais de três pessoas num grupo, de cidadãos livres bem intencionados, torna as decisões difíceis. Primeiro o grupo torna-se num comité com ou sem chefe de mesa. Depois é o caos. A barreira de comunicação torna o diálogo impossível. Pois para haver diálogo sem ruído, usando o nosso dom natural da voz, temos de falar um de cada vez. A nossa velocidade de assimilação, pensamento, e formulação de resposta verbal tem limites. Não se consegue fazer mais nada de útil. Apenas se fala e não sobra tempo para mais.

Conheço intimamente uma comunidade internacional online de sucesso, com 11 anos de existência, que ainda hoje persiste assim. Conheço intimamente uma empresa nacional de sucesso, com 25 anos de existência, que ainda hoje persiste assim. Acredito neste modelo. Acredito neste modelo, se os Arcontes forem pessoas de mérito: sábias e dialogantes.

Com menos de três pessoas a liderar o pt-jug, arriscamos-nos a sobrecarregar essa pessoa ou pessoas. Estas três pessoas devem ter capacidades complementares, mas aceitar trocar de chapéus numa emergência. Sugiro os seguintes perfis para cada Arconte:

Chefe da Logística
Chefe das Finanças
Chefe da Comunicação

As decisões executivas importantes devem ser tomadas com consenso dos três. Cada Arconte pode nomear ajudantes voluntários, por mérito, na medida que achar necessário. As finanças devem ser públicas e transparentes.

Os Arcontes de Atenas tinham mandato limitado, por exemplo, de um ano. Penso que devemos, para além disto, também ter um limite de número de mandatos para renovar o sangue da comunidade. Friso novamente: não devemos fossilizar. Se o fizermos, dispersamo-nos outra vez.

Se as finanças o justificassem, podíamos ter pessoas a tempo inteiro, pagar soldo a membros que vão a reuniões. Até pode aparecer um Ditador Benévolo, líder único a tempo inteiro, como Atenas na era de Péricles. Neste momento não vejo base de suporte para isso acontecer.

Practices of an Agile Developer : Working in the Real World

O Verão finalmente chegou, e a PT Comunicações conseguiu, pela segunda vez em semanas, cortar o telefone à vizinhança toda sem pré-aviso. Fiquei sem acesso à Internet e sem poder trabalhar. Foi uma boa motivação para pegar nos livros que tinha aqui para ler. Venho-vos falar de um livro, que achei muito interessante.


Este livro reúne um conjunto de regras, ou boas práticas, para um programador sénior ou líder de projecto que queira trabalhar seguindo uma metodologia ágil. Os autores são experientes na matéria. O Andy Hunt já tinha sido co-autor do livro The Pragmatic Programmer: From Journeyman to Master. O livro está cheio de bom senso, ressoa bem com a minha experiência, dá exemplos e conselhos práticos como resolver problemas de desenvolvimento. Não só a nível de bater código, mas também de design, bem como comunicação entre a equipa ou com o cliente. Penso que tem boas ideias para todos nós que estão interessados no desenvolvimento de software.

Cito-vos algumas destas regras:

Quick Fixes Become Quicksand
A former client of Andy’s had this very problem. None of the developers or architects understood the underlying data model of their domain, and over the course of several years the code base became littered with thousands of +1 and -1 corrections. Trying to add features or fix bugs in that mess was a hair-pulling nightmare (and indeed, many of the developers had gone bald by then). But like most catastrophes, it didn’t get like that all at once. Instead, it happened one quick fix at a time. Each quick fix—which ignored the pervasive, underlying problem—added up to a swamp-like morass of quicksand that eventually sucked the life out of the project.

Criticize Ideas, Not People
You’ve probably seen design discussions that get out of hand and become emotionally charged—decisions get made based on whose idea it was, not on the merits of the ideas themselves. We’ve been in meetings like that, and they aren’t pleasant. But it’s only natural. When Lee presents a new design, it’s easiest to say, “That’s stupid” (with the clear implication that Lee is stupid as well). It takes a little more effort to elaborate, “That’s stupid; you forgot to make it thread-safe.” And it actually takes real effort and thought to say the far more appropriate, “Thanks, Lee. But I’m curious, what will happen when two users log on at the same time?”

Damn the Torpedoes, Go Ahead
Courage doesn’t feel very comfortable, certainly not ahead of time. But it’s often the only way to remove obstacles that will just grow worse over time, and you’ll feel relief instead of increasing dread.

Keep Up with Change
“There is nothing permanent except change,” said Heraclitus. That has been true throughout history, but it’s especially true now. You’re in an exciting and ever-changing field. If you graduated with a degree in computer science or some related professional field and thought you were all done with learning, you were dead wrong.
...
Keep up with changing technology. You don’t have to become an expert at everything, but stay aware of where the industry is headed, and plan your career and projects accordingly.

Invest in Your Team
Find areas where you, or someone in your team who is knowledgeable, can help the rest of the team come up to speed (this has the added advantage that you can discuss how topics apply specifically to your applications or projects).

Know When to Unlearn
As technology marches on, things that used to be of paramount importance fall by the wayside. Not only aren’t they useful anymore, they can actually harm your effectiveness. When Andy was first programming, memory overlays were a big deal. You often couldn’t fit the whole program in main memory (48KB or so) at a time, so you had to split your program into chunks. When one chunk was swapped in, some chunk had to be swapped out, and you couldn’t call functions on one chunk from the other.
...
We’ve seen ten man-year J2EE projects go down in flames, only to be replaced with a month-long hack in PHP that delivers most of the features. Growing interest in languages such as PHP and web frameworks like Ruby on Rails show that developers are catching on that the old ways might not be cutting it anymore.
...
Old habits are hard to break and even harder to notice. The first step to unlearning is to realize that you’re using an outdated approach. That’s the hardest part. The other hardest part is actually letting go. Mental models and patterns of thought are built and refined at great cost over many years. One doesn’t discard them lightly. And it’s not that you really want to discard them completely, either. The previous memory overlay example is just a special case of manually maintaining a working set of items from a larger cache. The technique hasn’t gone away, although that implementation of it has. You don’t want to drill into the brain and snip all those dendrites off. Instead, you want to use older knowledge in context. Reinvent it and reuse it where applicable, but make sure you don’t drag along old habits just out of, well, habit.

Não me tinha ocorrido antes de ler o livro, mas mesmo com 29 anos, não escapo ao problema de ter de saber desaprender. Dei-me ao trabalho de aprender linguagens novas como Java, C#, Python e PHP, que não me foram ensinadas no curso, mas continuava a editar código com o vim. Desde que mudei para IDEs com suporte para refactoring, algo que não também não existia quando acabei o curso, reparei que a minha produtividade aumentou imenso.

Originalmente publicado no blog Português BITITES.

Software Livre e Aberto

Grandes homens da nossa civilização ocidental, homens que vieram antes de nós, disseram:

Uma mente educada distingue-se das outras por ponderar uma ideia mesmo sem a aceitar.
- Aristóteles

Quase toda a ideia sábia tem uma ideia oposta, não menos sábia, para a equilibrar.
- George Santayana

Como homem de ciência, educado nos moldes do método científico desde tenra idade, acredito que a única prova de validade de qualquer coisa é a experiência no terreno. Como homem de trabalho, penso que as acções falam mais alto que as palavras.

Estamos a criar uma coisa nova. Penso que deve ser dado espaço à experiência. Efectuar uma experiência não tem de ser caro: pode ser tão caro, em recursos financeiros e de tempo, como desejarmos se soubermos ser criativos.
Desejo que os melhores argumentos, argumentos sábios fortalecidos pela prova na prática, fortalecidos pela competição justa e amigável, transparentes como o cristal, vençam. Mesmo que esses argumentos não sejam os meus. Pois só assim sei que demos o nosso máximo e fizemos trabalho honesto. É assim que se trabalha nas meritocracias de sucesso do mundo do software livre e aberto. Comunidades nas quais participo com grande prazer e honra há mais de 10 anos.

A comunidade Java é hoje membro pleno, por direito próprio, desta comunidade do software livre e aberto: Java da Sun sob a bandeira do software livre. Apache Harmony, Eclipse, NetBeans sob a bandeira do software aberto. Todos nós temos as nossas preferências, mas lutamos para um fim comum : o sucesso da linguagem Java como ferramenta essencial de suporte à nossa actividade.

2007/07/31

Um novo início

Os portugueses têm a mania de dizer mal. E é-lhes difícil fazer críticas construtivas. Mais difícil ainda é chegarem-se à frente e contribuirem para uma comunidade.

Mas esta manhã, um grupo de portugueses que sabem o que está mal, são construtivos e decidiram fazer qualquer coisa acerca disso, juntaram-se para relançar o Grupo Português de Utilizadores de Java.

Dessa reunião saiu este blogue, uma mailing list, e uma lista de tarefas.

Parabéns a todos os presentes!