Pessoal, estou usando a criptografia DES.
No cliente eu passo a Chave e o texto para a funcao que vai criptografar e me retorna em byte o resultado, assim transmito para o servidor.
Já no servidor recebe o texto criptografado, e para descriptografar é necessário passar em byte. Mas o texto transmitido é em formato de string, e se uso a funcao:
byte [] byte_ex1 = (new String(buff.toString())).getBytes();
Ao converter bytes para uma string, alguns dos bytes são perdidos (a conversão é irreversível).
Portanto, é necessário codificar os bytes (usando hexadecimal, base-64 ou base-85) antes de convertê-los para uma string.
Vou dar um exemplo:
class StringNaoEhArrayDeBytes {
public static void main(String[] args) throws Exception {
byte[] bytes = new byte[256];
// Primeiramente estamos preenchendo o array "bytes" com
// os valores de 0 até 255
for (int i = 0; i < bytes.length; ++i) {
bytes[i] = (byte) i;
}
// Agora vamos converter ingenuamente esse array de bytes para uma string.
// Vamos usar o "encoding" Windows-1252 porque é o que dá menos problemas
String s = new String (bytes, "Windows-1252");
// Vamos desconverter a string para um array de bytes.
byte[] bytes2 = s.getBytes ("Windows-1252");
// Agora vamos conferir para ver quais dos bytes foram convertidos erroneamente.
for (int i = 0; i < bytes.length; i++) {
byte b = (byte) i;
if (bytes2[i] != b) {
System.out.printf ("O byte 0x%02X foi perdido e transformado em 0x%02X (%c) %n",
(byte) i,
bytes2[i],
(char) bytes2[i]);
}
}
}
}
A saída desse programa é:
O byte 0x81 foi perdido e transformado em 0x3F (?)
O byte 0x8D foi perdido e transformado em 0x3F (?)
O byte 0x8F foi perdido e transformado em 0x3F (?)
O byte 0x90 foi perdido e transformado em 0x3F (?)
O byte 0x9D foi perdido e transformado em 0x3F (?)
Não adianta mudar o encoding (que nesse caso é Windows-1252). Vai dar problema com algum byte. (Teste, por exemplo, com "ASCII" e "UTF-8"). No caso "ISO-8859-1" parece que funciona, mas veja se isso também vale para outras versões do Java.
Chego a conclusão que usar a criptografia simetrica RSA de cliente para servidor numa aplicação J2me parece ser impossível.
A criptografia peguei do org.bouncycastle e me parece que funciona só para uma aplicação e nao para cliente servidor.
[/quote]
Aham - RSA não é simétrica e deve ser usada com cuidados.
Um dos principais cuidados é que ela é bem lenta em ambiente Mobile devido à grande capacidade de processamento que ela exige; mas acho que esse é o único problema.
Outra coisa é que RSA só é útil para criptografar chaves, não os dados em si.
A terceira coisa é que ela trabalha com BigIntegers, não com arrays de bytes, então você precisa especificar um “padding” adequado se for usá-la para criptografar uma chave.
Mas ela poderia ser usada em ambiente Mobile; acho só que você está se confundindo todo com RSA, que não é para amadores.
acho que esse problema ele vai ter mais pra frente. para mim o problema agora é outro (linha 9 do cliente):
byte[] valor = null;
(...)
txt = valor.toString();
(...)
OS.write(txt.getBytes());
Ou seja, quando ele faz um toString de um array, o retorno não vai ser os bytes trasformados num objeto String e sim algo como B@1a2b3c4d5e6f.[/quote]
Para converter um array de bytes em uma string, NÃO USE toString e sim new String (byte[], String) onde o primeiro parâmetro é o array a ser convertido e o segundo é o encoding adequado. (Não sei se isso existe em JavaME).
acho que esse problema ele vai ter mais pra frente. para mim o problema agora é outro (linha 9 do cliente):
byte[] valor = null;
(...)
txt = valor.toString();
(...)
OS.write(txt.getBytes());
Ou seja, quando ele faz um toString de um array, o retorno não vai ser os bytes trasformados num objeto String e sim algo como B@1a2b3c4d5e6f.[/quote]
Para converter um array de bytes em uma string, NÃO USE toString e sim new String (byte[], String) onde o primeiro parâmetro é o array a ser convertido e o segundo é o encoding adequado. (Não sei se isso existe em JavaME).
[/quote]
eu não disse para ele fazer isso, mas sim apontei o erro.
“[B@f828ed68” quer dizer: “O array de bytes (”[B") que tem o default hash code 0xf828ed68". Isso não serve para absolutamente nada, exceto para você perceber que não é para usar “toString” para um array de bytes.
O que você deve fazer para converter um array de bytes para uma string (e aceitando que pode haver perdas) é
String s = new String (texto); // onde texto é um array de bytes, não criptografados
ou se isto estiver disponível,
String s = new String (texto, "ISO-8859-1"); // onde texto é um array de bytes.
Pessoal finalmente consegui fazer funcionar cliente/servidor para J2me com a criptografia simetrica do Bouncy Castle.
Onde eu passo o texto que quero criptografar para o método que me retorna um array de bytes e para descriptografar passo o array de bytes que me devolve o texto em string. Obrigado pela atenção de todos. Qualquer dúvida meu email é alerocha19@ig.com.br
// A simple example that uses the Bouncy Castle
// lightweight cryptography API to perform DES
// encryption of arbitrary data.
public class Encryptor {
private BufferedBlockCipher cipher;
private KeyParameter key;
// Initialize the cryptographic engine.
// The key array should be at least 8 bytes long.
public Encryptor( byte[] key ){
/*
cipher = new PaddedBlockCipher(
new CBCBlockCipher(
new DESEngine() ) );
*/
cipher = new PaddedBlockCipher(
new CBCBlockCipher(
new BlowfishEngine() ) );
this.key = new KeyParameter( key );
}
// Initialize the cryptographic engine.
// The string should be at least 8 chars long.
public Encryptor( String key ){
this( key.getBytes() );
}
// Private routine that does the gritty work.
private byte[] callCipher( byte[] data )
throws CryptoException {
int size =
cipher.getOutputSize( data.length );
byte[] result = new byte[ size ];
int olen = cipher.processBytes( data, 0,
data.length, result, 0 );
olen += cipher.doFinal( result, olen );
if( olen < size ){
byte[] tmp = new byte[ olen ];
System.arraycopy(
result, 0, tmp, 0, olen );
result = tmp;
}
return result;
}
// Encrypt arbitrary byte array, returning the
// encrypted data in a different byte array.
public synchronized byte[] encrypt( byte[] data )
throws CryptoException {
if( data == null || data.length == 0 ){
return new byte[0];
}
cipher.init( true, key );
return callCipher( data );
}
// Encrypts a string.
public byte[] encryptString( String data )
throws CryptoException {
if( data == null || data.length() == 0 ){
return new byte[0];
}
return encrypt( data.getBytes() );
}
// Decrypts arbitrary data.
public synchronized byte[] decrypt( byte[] data )
throws CryptoException {
if( data == null || data.length == 0 ){
return new byte[0];
}
cipher.init( false, key );
return callCipher( data );
}
// Decrypts a string that was previously encoded
// using encryptString.
public String decryptString( byte[] data )
throws CryptoException {
if( data == null || data.length == 0 ){
return "";
}
return new String( decrypt( data ) );
}