Bom dia a todos,
atenção isso é um post técnico
Se vocês usam a classe CipherInputStream para fazer criptografia de dados nunca devem ter percebido uma coisa engraçada. O caso é: eu precisava limitar o tamanho de um stream que poderia ser usado em um serviço Rest e para tal eu criei um wrapper da classe InputStream e quando ele fosse ler o InputStream , sempre contasse os dados e se chegasse em tal limite , lança uma exceção. O problema é que quando eu passava esse wrapper com 1 milhão de bytes dentro do InputStream e com limite de 1 milhão de bytes para a CipherInputStream , as vezes ele passava e as vezes ele lançava exceção.
Fui descobrir que essa bendita classe ( CipherInputStream) do java não é consistente em relação ao retorno do dado criptografado o que eu acredito ser totalmente aceitável, mas isso não está documentado em lugar nenhum.
A lição é : tamanho do retorno do CipherInputStream não tem relação de 1 para 1 com o tamanho do InputStream que você coloca no construtor dele.
Até mais.
quinta-feira, 3 de outubro de 2013
quinta-feira, 29 de agosto de 2013
Problemas com SVN
Bom dia esse é um post técnico.
Se você está com problemas com autorização do SVN depois de uma mudança de senha do seu login no windows e estiver usando eclipse com o plugin do Subclipse é só ir em:
Preferences->Team -> SVN -> SVN Interface
E mudar de JavaHL para SVNKit.
Tente usar de novo e ele pedirá a senha.
Fim.
Se você está com problemas com autorização do SVN depois de uma mudança de senha do seu login no windows e estiver usando eclipse com o plugin do Subclipse é só ir em:
Preferences->Team -> SVN -> SVN Interface
E mudar de JavaHL para SVNKit.
Tente usar de novo e ele pedirá a senha.
Fim.
quinta-feira, 8 de agosto de 2013
Perl - Debugando erros de DB
Bom dia pessoal,
Este é um post técnico.
Esse é mais um post sobre perl, dessa vez para quem precisa debugar erros no banco de dados. Usando o DBI , uma api bastante utilizada para fazer chamadas em bancos mysql, oracle etc, vocês podem precisar fazer processos em batch. Quer dizer, fazer várias chamadas no bd fazendo um commit só. O problema é que se der um erro no meio dessas chamadas, o erro padrão que é lançado é bem preciso sobre "como errou" e não sobre "o que errou". Para o programador poder verificar isso mais facilmente é bem simples. Só basta usar o método TRACE da API. Exemplo abaixo:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Este é um post técnico.
Esse é mais um post sobre perl, dessa vez para quem precisa debugar erros no banco de dados. Usando o DBI , uma api bastante utilizada para fazer chamadas em bancos mysql, oracle etc, vocês podem precisar fazer processos em batch. Quer dizer, fazer várias chamadas no bd fazendo um commit só. O problema é que se der um erro no meio dessas chamadas, o erro padrão que é lançado é bem preciso sobre "como errou" e não sobre "o que errou". Para o programador poder verificar isso mais facilmente é bem simples. Só basta usar o método TRACE da API. Exemplo abaixo:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
use DBI;### Remove any old trace filesunlink 'dbitrace.log' if -e 'dbitrace.log';### Connect to a databasemy $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" );### Set the tracing level to 1 andprepare()DBI->trace( 1 );doPrepare();### Set trace output to a file at level 2 andprepare()DBI->trace( 2, 'dbitrace.log' );doPrepare();### Set the trace output back to STDERR at level 2 andprepare()DBI->trace( 2, undef );doPrepare();exit;### prepare a statement (invalid to demonstrate tracing)sub doPrepare {print "Preparing and executing statement\n";my $sth = $dbh->prepare( "SELECT * FROM megalith" );$sth->execute();return;}~
### font : http://oreilly.com/catalog/perldbi/chapter/ch04.html
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
O trace só será invocado para cada método que for realizado e acontecer algo de anormal, AKA erros. Legal é que você pode enviar para uma saída esse trace com o segundo argumento do método. Melhor do que do que isso, para cada erro você pode manipula-lo com um :
$statement->trace_msg ( " SUA STRING AQUI");
Quer dizer que para cada erro, você pode personalizar o que você estava mandando, e isso resolve o problema da falta de verbosidade do nosso amigo "erro padrão do database". ( link )
FIM.
segunda-feira, 29 de julho de 2013
"Hot reload" de atributos de arquivo com Java EE usando Apache Common Configuration
Boa tarde pessoal,
ESTE É UM POST TÉCNICO
ESTE É UM POST TÉCNICO
O assunto de hoje é sobre a necessidade de se carregar de forma dinâmica atributos em uma aplicação (geralmente web) sem precisar fazer restart do server. Fazendo restart do server muitos leitores poderão falar sobre o ServletContext, que se você deixar o código preparado pode receber mudanças e no restart ele vai ler as mudanças e aplica-las. Estamos falando aqui de aplicações que não podem parar e não podem ter o "tempo do restart" de folga. Umas solução bastante simples é usar a lib Apache Common Configuration ( link ). Com essa biblioteca você pode setar vários tipos de "estratégias de reload" de configurações. Vou falar das 3 principais: FileChangedReloadingStrategy, InvariantReloadingStrategy, ManagedReloadingStrategy. A FileChangedReloadingStrategy é a mais utilizada. Toda vez que você ler um arquivo de properties, ele verificar se essa nova leitura bate com a última leitura, se não bater, ele recarrega os atributos. A InvariantReloadingStrategy é uma estratégia para NUNCA recarregar os atributos, quer dizer, uma vez em memória não serão recarregados até o próximos restart da aplicação. E por último o ManagedReloadingStrategy em que você pode "manualmente" fazer o reaload dos properties em seu código. Vamos ao exemplo:
PropertiesConfiguration config = new PropertiesConfiguration("minhasPropiedades.properties");
config.setReloadingStrategy(new FileChangedReloadingStrategy()); // se desejar usar essa estratégia.
E... só. Fácil não? Agora você tem na sua aplicação a possibilidade de recarregar atributos de um arquivo de properties sem precisar fazer restart da mesma.
Fim.
ps: estou pensando em alguns temas não técnicos para escrever mas não estou com ideias maduras. Até lá vai ser coisas técnicas mesmo. Adiós!
sexta-feira, 26 de julho de 2013
Criptografia AES de 256 bits de chaves simétricas com Perl
Bom dia a todos!
use Crypt::CBC;
use MIME::Base64;
# /*Requisicao: texto=vivaobrasil
# Resposta: status=0, texto-criptografado=t7rvuxbe6dBRfhDjlFPjtw==,
# IV=ABESpFdKYLTkiqkOdA+F+A==, key-id=2929
# symmetric key :"bncM9yhZfwxF5NomWErbIrvbaZmE3AwPcMxgSneROiU="
# */
my $dataPlain = "Sole Deo Gloria";
my $keyundecoded ="bncM9yhZfwxF5No3WErbIrvbaZmEfAwPcMxgSneROi4=";
my $key = decode_base64($keyundecoded);
my $ivundecoded = "1234567890123456789012=="; # precisa ter 16 bytes decoded
my $iv = decode_base64($ivundecoded);
my $encriptedData = "t7rvuxbe6dBRfhDjlFPjtw==";
my $encriptedDecodedData = decode_base64($encriptedData);
my $cipher = Crypt::CBC->new({
key => $key,
cipher => "Crypt::Rijndael",
iv => $iv,
literal_key => 1,
header => "none",
keysize => 32
});
my $encryptedData = $cipher->encrypt($dataPlain);
print "\n Encrypted is : +$encriptedData";
my $plaintext = $cipher->decrypt($encryptedData);
print "\n Decrypted is : $plaintext" ;
------------------------------------------------------------------------------------------------
Fim.
Hoje vou demonstrar como é possível decodificar uma informação codificada com algoritmo AES de 256 bis a partir de uma chave já gerada e de um iv já gerado e encodados com base 64. Lembrando que a forma mais segura de trafegar os dados por uma rede é encoda-los em alguma base, a base mais comum é a 64 mas existem outras, com um pouco de pesquisa vão descobrir outros métodos que possam servi-los melhor, por fim acredito que Base 64 deva servir para quase todos os propósitos mais comuns de criptografia. É importante testar seus algoritmos de criptografia e descriptografia em mais de uma linguagem para provar que o seu código não está ligado a apenas uma linguagem, por exemplo, criptografar e encodar em java e depois decodificar em Perl como o exemplo abaixo faz. O algoritmo AES está muito bem explicado aqui ( link ) . Vamos ao código em perl, lembrando que é preciso ter os pacotes "Crypt::CBC" e "MIME::Base64" . Para baixa-los, no processo padrão, é só usar cpanm + "nome do pacote" , se o cpanm estiver instalado em seu ambiente de desenvolvimento. Eu estou desenvolvendo com windows atualmente e isso não funcionou comigo, tive que digitar "cpan" no "cmd" e lá dentro e digitar "install "nomedo::Pacote"". Vamos ao código:
------------------------------------------------------------------------------------------------
#!/usr/bin/perluse Crypt::CBC;
use MIME::Base64;
# /*Requisicao: texto=vivaobrasil
# Resposta: status=0, texto-criptografado=t7rvuxbe6dBRfhDjlFPjtw==,
# IV=ABESpFdKYLTkiqkOdA+F+A==, key-id=2929
# symmetric key :"bncM9yhZfwxF5NomWErbIrvbaZmE3AwPcMxgSneROiU="
# */
my $dataPlain = "Sole Deo Gloria";
my $keyundecoded ="bncM9yhZfwxF5No3WErbIrvbaZmEfAwPcMxgSneROi4=";
my $key = decode_base64($keyundecoded);
my $ivundecoded = "1234567890123456789012=="; # precisa ter 16 bytes decoded
my $iv = decode_base64($ivundecoded);
my $encriptedData = "t7rvuxbe6dBRfhDjlFPjtw==";
my $encriptedDecodedData = decode_base64($encriptedData);
my $cipher = Crypt::CBC->new({
key => $key,
cipher => "Crypt::Rijndael",
iv => $iv,
literal_key => 1,
header => "none",
keysize => 32
});
my $encryptedData = $cipher->encrypt($dataPlain);
print "\n Encrypted is : +$encriptedData";
my $plaintext = $cipher->decrypt($encryptedData);
print "\n Decrypted is : $plaintext" ;
------------------------------------------------------------------------------------------------
Fim.
quinta-feira, 25 de julho de 2013
Nome de variáveis em programação
Bom dia pessoal!
ESTE É UM POST TÉCNICO.
1 - String x ;
2 - byte[] x2;
3 - int x3;
etc
etc.
Agora melhorou. Mas não está boa ainda. Esse nome de variável está muito grande. E ele fica difícil de guardar na memória enquanto você lê o código e debuga na sua mente. Imagina um programa só com variáveis gigantes... seria um "out of memory error" ( link ) na sua cabeça. Fiz uma brincadeira, mas o assunto é sério, não devemos dar nomes gigantes a variáveis pois eles são difíceis de guardar enquanto se lê o código. Agora estão se perguntando: "Mas então, se não podemos ser curtos demais, nem longos demais, como saberemos que o nome da variável é um nome perfeito?" . Esse é o ponto, nunca poderemos afirmar que o nome da variável está perfeito por que isso é uma opção pessoal. O que podemos indicar são nomes ruins, isso é fácil. Mas um excelente... é muito difícil. O ideal é você conseguir fazer que um nome de variável seja tanto descritiva quanto concisa, e a intersecção dessas duas qualidades faz a qualidade do nome de suas variáveis subir. Aqui vão algumas sugestões para a resolução do nosso pequeno exercício:
1- String nomeClienteBD;
2- String nameClientDB;
3- String solicitanteNome;
ESTE É UM POST TÉCNICO.
Hoje vou falar sobre um tópico muito, mas MUITO importante na área de programação. Antes de começar vou dar os devidos créditos dessa sabedoria aos que merecem, Jonas Abreu e Michel Forster, dois programadores que me ensinaram o valor do nome de uma variável. Vocês devem estar se perguntando "Mas um post inteiro sobre o nome de uma variável? Mas isso é algo tão trivial para mim..." , é ai que você se engana Jovem Gafanhoto, o nome que você da as variáveis é tão importante para o código quanto por exemplo o título dos capítulos de um livro ( ou se eles terão um título). Como todo post técnico será feito devagar e com bastante calma, para que todo mundo possa entender, mesmo os que não tem proficiência em alguma linguagem de programação. Acredito que essa seja um dos "Pontos Fundamentais da Programação", quero dizer, uma das condições sine qua non para um excelente/mito/lendário programador. A despeito da linguagem que você programa todos os programadores vão ter que declarar variáveis um dia. Vou escrever em Java que a linguagem que eu mais tenho contato atualmente mas o que eu vou demonstrar pode ser aplicado em basicamente qualquer linguagem. Esse processo de aprender a declarar variáveis é simples e é uma das primeiras coisas que você aprende na área. Alguns exemplos de declaração de variável são :
1 - String x ;
2 - byte[] x2;
3 - int x3;
etc
etc.
Nesse exemplo estamos somente declarando primeiro o tipo "String, array de byte, e int" e depois o bendito nome da variável. A pergunta que eu vos faço é simples, lendo o nome da primeira variável você sabe o que ela guarda? O que guarda a String x? Por que ela é uma string e não um array de chars? E será que o Goku vai conseguir matar o freeza antes de eu me casar? Brincadeiras a parte, é sobre esse assunto que o texto é dedicado. Como dar um bom nome para uma variável. O caso é que vários e vááááááarios artigos já falam extensivamente sobre isso, pessoas com um gabarito bem maior que o meu já falaram em palestras etc. Mas vou abordar o conceito de maneira introdutória para que isso possa aguçar a curiosidade dos meus leitores técnicos. Voltando as variáveis, vamos pensar que elas estão em um contexto de um POJO ( link ) que representa o pedido dos clientes. Sem poder ler o resto do código o que essas variáveis representam do pedido? Não temos a mínima ideia. Agora se mudarmos para algo assim:
1- String nome;
2- byte[] produtos;
3- int numero;
Agora mudou de figura. Agora sabemos que o número 1 representa um nome, o número 2 representa os produtos do pedido e o número 3 representa um número. Os nomes melhoraram? Com certeza. Eles estão bons? Com certeza não. Vamos focar no número 1. Agora lendo o nome da String podemos rapidamente identificar que é o nome de algo, mas do que? É o nome da atendente que registrou o pedido ou o nome do solicitante? É um nome fictício do sistema ou o nome real do banco de dados? É um nome completo ou só o sobrenome? Depois de muita investigação no código você descobre que é o primeiro nome de cadastro do cliente no banco de dados. Então vamos mudar o nome da variável para:
1- String primeiroNomeDoClienteNoBancoDeDadosString;
Agora sim. Temos um nome de variável que, sem precisar saber a lógica do programa , sabemos exatamente o que ela guarda. Mas ela está boa? Ainda não. Ela tem dois erros básicos ao se atribuir nome as variáveis. O primeiro é usar "Do"/"No"/"De" isso não faz sentido. Sem esses "conectivos" poderíamos entender muito bem e ficaria:
1- String primeiroNomeClienteBancoDadosString;
Agora falando especificamente de java, é muito tentador dar o nome do tipo as coisas que fazemos. Por exemplo uma interface chamada "CacheDistribuedInterface". Mas de novo, isso não faz sentido nenhum em Java, pois java é uma linguagem fortemente tipada. ( link ) Sendo fortemente tipada, você programador, não precisa escrever o tipo do nome da variável por que ela simplesmente não vai mudar na execução do programa. ( Se você tem uma variável que é uma interface e o que pode mudar é o tipo de implementação que ela está guardando, mas o tipo dela não mudará). Arrumando essa pequena "falha" :
1- String primeiroNomeClienteBancoDados;
1- String nomeClienteBD;
2- String nameClientDB;
3- String solicitanteNome;
4 - String clientNameDb;
etc
etc
etc
Fim.
quarta-feira, 24 de julho de 2013
Janelas, varandas, horizontes enfim....
Bom dia pessoal,
Hoje percebi um fenômeno interessante. Por que as pessoas são tão fixadas em janelas e varandas? Vou explicar o caso. Primeiro vou relatar vários exemplos relacionados ao tema. Aqui no meu trabalho a janela do banheiro a bem ampla e muitas pessoas quando escovam os dentes ficam olhando pela janela para ver o que acontece na rua. No meu trabalho também, na copa tem uma janela gigante, em que várias pessoas ficam olhando pela janela e tomando café enquanto estão no descanso. Outro exemplo é quando vem amigos no meu apartamento, quase em todas as vezes eles querem ir na varanda olhar. Não me excluo desse fenômeno pois quando eu escovo os dentes lá no trabalho também fico olhando pela grande janela. Mas o que estamos procurando? Será que esse reflexo involuntário de ficar observando a paisagem seja algo primitivo de nossa existência? Talvez, olhamos involuntariamente para essas "janelas" na esperança de encontrar algo que foi perdido a muito tempo, algo que tínhamos quando nossa raça era nômade. Quando éramos nômades não existiam janelas, pois o mundo todo podia ser nossa casa. Paisagens eram todas nossas, e podíamos nos deslocar para qualquer lugar. Será essa natureza? Será que por mais que tenhamos desenvolvido uma civilização sedentária, o nosso instinto continue nômade? Não sei a resposta para nenhuma dessas perguntas, mas acredito que seria uma pesquisa interessante saber a razão dessa fixação das pessoas por janelas/varandas.
Fim.
Assinar:
Postagens (Atom)