Cryptage via AES et transfert UDP

babylone78 Messages postés 8 Date d'inscription mardi 13 avril 2004 Statut Membre Dernière intervention 11 janvier 2011 - 24 juin 2010 à 11:35
babylone78 Messages postés 8 Date d'inscription mardi 13 avril 2004 Statut Membre Dernière intervention 11 janvier 2011 - 28 juin 2010 à 09:08
Bonjour,

Je veux envoyer un message entre un serveur et un client via le protocole UDP et en cryptant le message avec l'algorithme symétrique AES.
Quand je crypte et decrypte le message dans le même programme , ca marche pas de souci mais lorsque je crypte le message par le sender , l'envoie au client qui le decrypt, j'obtiens une exception :
javax.crypto.BadPaddingException: Given final block not properly padded

voici le code du sender
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;


public class sender {


public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, UnknownHostException, IllegalBlockSizeException, BadPaddingException{
int taille = 1024 ;
String str = "2321321412363698";
AES aesCipher = new AES(str.getBytes());
int portUdpSend = 8536 ;
String clientname = args[0];
InetAddress client = InetAddress.getByName(clientname);
Scanner sc = new Scanner(System.in);
 byte[] buffer;
while(true){
System.out.println("msg a envoyer ? ");
String msg = sc.nextLine();
buffer = msg.getBytes();
buffer = aesCipher.encrypt(buffer);
DatagramPacket dataUdp = new DatagramPacket(buffer, buffer.length, client, portUdpSend);
try{
            	DatagramSocket socketUdp = new DatagramSocket();
            	try{
            	socketUdp.send(dataUdp);
            	}
            	catch(IOException ex){System.out.print("datagram creation error : msg not sended");}
            }
            catch (SocketException ex){System.out.print("socket error : msg not sended");} 
}
}
}


le code du client
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;


public class client {



public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException{
int taille = 1024 ;
String str = "2321321412363698";
AES aesCipher = new AES(str.getBytes());
int portUdpReceive = 8536 ;
try
{
DatagramSocket socket = new DatagramSocket(portUdpReceive);
while (true) {
            byte buffer[] = new byte[taille];
            DatagramPacket data = new DatagramPacket(buffer, buffer.length);
            try{
            socket.receive(data);
            System.out.print("data received from server  :  ");
            try{
            byte[] decrypted_data = aesCipher.decrypt(data.getData());
            String s new String(decrypted_data);System.out.println("msg decrypted "+s);				            				            
            }
            catch(BadPaddingException ex){System.out.print("cipher error : BadPaddingException");ex.printStackTrace();}
            catch(IllegalBlockSizeException ex){System.out.print("cipher error : IllegalBlockSizeException");ex.printStackTrace();}
            }
            catch(IOException e){ System.out.println("erreur socket when receive message");}
}				    
}
catch(SocketException e){ System.out.println("erreur creation de socket");}
}
}


et mon algo de cryptage :
import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;

public class AES {

  private byte[] key;
  private SecretKeySpec skeySpec;
  public Cipher cipher_encrypt;
  public Cipher cipher_decrypt;
  //
  /**
   * class implementant l'algorithme AES 128 bit 
   */
  public AES() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
  	// Get the KeyGenerator
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    kgen.init(128); // 192 and 256 bits may not be available
    // Generate the secret key specs.
    SecretKey skey = kgen.generateKey();
    key = skey.getEncoded();
    skeySpec = new SecretKeySpec(key, "AES");
    cipher_encrypt = Cipher.getInstance("AES");
    cipher_encrypt.init(Cipher.ENCRYPT_MODE, skeySpec);
    cipher_decrypt = Cipher.getInstance("AES");
    cipher_decrypt.init(Cipher.DECRYPT_MODE, skeySpec);
  }
  
  public AES(byte[] key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException{
  	skeySpec = new SecretKeySpec(key, "AES");
    cipher_encrypt = Cipher.getInstance("AES");
    cipher_encrypt.init(Cipher.ENCRYPT_MODE, skeySpec);
    cipher_decrypt = Cipher.getInstance("AES");
    cipher_decrypt.init(Cipher.DECRYPT_MODE, skeySpec);
  }
  
  public byte[] getKey(){return key;}

  public byte[] encrypt(byte[] b) throws IllegalBlockSizeException, BadPaddingException{
  return cipher_encrypt.doFinal(b);
  }
  public byte[] decrypt(byte[] b) throws IllegalBlockSizeException, BadPaddingException{
  return cipher_decrypt.doFinal(b);
  }
}


Quelqu'un a une idée d'où cela pourrait venir ?

merci!

2 réponses

babylone78 Messages postés 8 Date d'inscription mardi 13 avril 2004 Statut Membre Dernière intervention 11 janvier 2011
28 juin 2010 à 09:06
Bon c'est bon j'ai trouvé, c'est parce que mon message est trop petit et le protocole udp bourre la trame avec des 0 pour completer. du coup pour recuperer le message dans mon client il faut faire :

 
buffer = new byte[taille];
data = new DatagramPacket(buffer, buffer.length);
 try{
socket.receive(data);
System.out.print("data received from server  :  ");
        datawithnopadding = new byte[data.getLength()] ;
for (int i = 0; i<data.getLength();i++){
datawithnopadding[i] = data.getData()[i];
}
in = new ByteArrayInputStream(datawithnopadding);
out = new ByteArrayOutputStream();
AES.crypt(in, out, aesCipher.cipher_decrypt);
 String s = new String(out.toByteArray());
System.out.println("msg decrypted = "+s);	
 }
 catch(IOException e){ System.out.println("erreur socket when receive message");}


voila
0
babylone78 Messages postés 8 Date d'inscription mardi 13 avril 2004 Statut Membre Dernière intervention 11 janvier 2011
28 juin 2010 à 09:08
ah oui AES.crypt je l'ai trouvé sur internet, si j'ai bien compris faire juste un doFinal n'est pas satisfaisant si on a un message trop long a crypter.

 public static void crypt(InputStream in, OutputStream out, Cipher cipher)
      throws IOException
  {
      int blockSize = cipher.getBlockSize();
      int outputSize = cipher.getOutputSize(blockSize);
      byte[] inBytes = new byte[blockSize];
      byte[] outBytes = new byte[outputSize];
      
      int inLength = 0;
      boolean done = false;
      while(!done)
      {
          inLength = in.read(inBytes);
          if(inLength == blockSize)
          {
              try
              {
                  int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
                  out.write(outBytes, 0, outLength);
              }
              catch(ShortBufferException e)
              {
                  e.printStackTrace();
              }
          }
          else
              done = true;
      }
      
      try
      {
          if(inLength > 0)
              outBytes = cipher.doFinal(inBytes, 0, inLength);
          else
              outBytes = cipher.doFinal();
          out.write(outBytes);
      }
      catch(IllegalBlockSizeException e)
      {
          e.printStackTrace();
      }
      catch(BadPaddingException e)
      {
          e.printStackTrace();
      }
  }
0
Rejoignez-nous