IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

Chiffrement AES entre Java et Objective-C


Sujet :

Java

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    ingénieur d'études
    Inscrit en
    Juillet 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2011
    Messages : 36
    Points : 29
    Points
    29
    Par défaut Chiffrement AES entre Java et Objective-C
    Bonjour,

    J'ai un leger soucis, je dois faire communiquer un client mobile (ios) avec un serveur JAVA par communications chiffrées. J'utilises pour cela une clé partagée AES.

    Mon problème est le suivant : le client chiffre le message, mais le serveur n'arrive pas à le dechiffrer.

    Ils ont pourtant la même clé, le même mode "EBC", et le même padding PKCS7.

    Voici le client IOS
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    char keyPtr[kCCKeySizeAES128+1];
    keyPtr = 1234567890123456;
     
    CCCryptorStatus ret = CCCrypt(kCCEncrypt,
                                      kCCAlgorithmAES128,
                                      kCCOptionECBMode+kCCOptionPKCS7Padding,
                                      keyPtr,
                                      kCCKeySizeAES128,
                                      NULL,
                                      plainBytes, sizeof(plainBytes),
                                      buffer, bufferSize,
                                      &bytesEncrypted);
    et le serveur JAVA
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    byte[] key = "1234567890123456".getBytes();
    SecretKey sk = new SecretKeySpec(key,"AES");
    Cipher decrypt = Cipher.getInstance("AES/ECB/PKCS7Padding");
    decrypt.init(Cipher.DECRYPT_MODE,sk);
    messageDecrypté = decrypt.doFinal(message);
    Y a t-il un problème dans ma programmation ??

    Merci

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par olivpepette Voir le message
    Y a t-il un problème dans ma programmation ??
    plusieurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char keyPtr[kCCKeySizeAES128+1];
    keyPtr = 1234567890123456;
    ce n'est pas ainsi qu'on initialise un tableau de char en C.
    (et d'ailleurs ce code ne compile même pas…)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    keyPtr,
    kCCKeySizeAES128,
    CCCrypt attend la longueur réelle de la clé : pas la longueur maximum supportée…
    donc "strlen(keyPtr)" …

    et on peut s'attendre à la même erreur sur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    plainBytes, sizeof(plainBytes),
    c'est sans doute "strlen(plainBytes)" qu'il faudrait là aussi
    mais comme on ne voit pas sa déclaration…

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    ingénieur d'études
    Inscrit en
    Juillet 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2011
    Messages : 36
    Points : 29
    Points
    29
    Par défaut
    Merci de ta réponse rapide,

    Cependant, le problème semble ne pas venir de là. Le problème que j'ai est que mon serveur (java), ne décrypte pas bien le message crypté par le client(objective-c).

    L'erreur qui apparait est : "last block incomplete in decryption".

    d'où cela peut-il venir ?

  4. #4
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par olivpepette Voir le message
    Merci de ta réponse rapide,

    Cependant, le problème semble ne pas venir de là. Le problème que j'ai est que mon serveur (java), ne décrypte pas bien le message crypté par le client(objective-c).

    L'erreur qui apparait est : "last block incomplete in decryption".

    d'où cela peut-il venir ?
    si la clé n'est pas juste, si la longueur du bloc chiffré n'est pas correcte, …
    comment voulez-vous que le déchiffrage avec la bonne clé fonctionne ?

    (sans parler de ce que vous ne montrez pas : comment vous transmettez les données au serveur… si vous faites une requête HTTP : est-ce que les données sont bien "URL encoded" pour une requête Web…)

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    ingénieur d'études
    Inscrit en
    Juillet 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2011
    Messages : 36
    Points : 29
    Points
    29
    Par défaut
    Citation Envoyé par JeitEmgie Voir le message
    si la clé n'est pas juste, si la longueur du bloc chiffré n'est pas correcte, …
    comment voulez-vous que le déchiffrage avec la bonne clé fonctionne ?

    (sans parler de ce que vous ne montrez pas : comment vous transmettez les données au serveur… si vous faites une requête HTTP : est-ce que les données sont bien "URL encoded" pour une requête Web…)
    Au niveau de la clé, il n'y a pas de problèmes, c'est la même des deux cotés (une clé de 16 octets = 128 bits).

    Pour la transmission des données au serveur, je passes par un message SOAP, et je fais d'abord un encodage en base64.

    Je vais regarder au niveau de la longueur du bloc chiffré si il n'y a pas de problèmes.

  6. #6
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par olivpepette Voir le message
    Au niveau de la clé, il n'y a pas de problèmes, c'est la même des deux cotés (une clé de 16 octets = 128 bits).
    Non : justement le code que vous postez montre sans aucun doute que la clé n'est pas la même !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    keyPtr = 1234567890123456;
    ce n'est pas la même chose que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    strcpy(keyPtr, "1234567890123456") ;
    ou alors postez le vrai code COMPLET (avec la déclaration et l'initialisation de TOUTES les variables utilisées dans l'appel à CCCrypt) que vous compilez : parce que ce vous avez mis ici ne compile même pas… donc on est en droit de se demander ce que vous exécutez réellement.

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    ingénieur d'études
    Inscrit en
    Juillet 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2011
    Messages : 36
    Points : 29
    Points
    29
    Par défaut
    voici donc le vrai code que j'utilises pour le chiffrement AES

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
     
    (NSData *)EncryptString:(NSString*)plainString
    					 key:(NSString *)keyString {
    	NSLog(@"\n\n CRYPTAGE\n\n");	
     
    	NSData * encryptedData;
     
        if (plainString == nil || [plainString length] == 0){
    		NSLog(@"plainString est vide");
            return nil;
    	}
     
        // CString for the symmetric key
        char keyPtr[kCCKeySizeAES128];
        [keyString getCString:keyPtr
                    maxLength:sizeof(keyPtr)
                     encoding:NSASCIIStringEncoding];
    	NSLog(@"keyString = %s  taille = %d",keyString, sizeof(keyString));
        // CString for the plain text
        char plainBytes[[plainString length]];
        [plainString getCString:plainBytes
                      maxLength:sizeof(plainBytes)
                       encoding:NSASCIIStringEncoding];
     
        size_t bytesEncrypted = 0;
     
        // Allocate the space for encrypted data
        NSUInteger dataLength = [plainString length];
    	NSLog(@"datalength = %d",dataLength);
        size_t bufferSize = dataLength + kCCBlockSizeAES128;
    	NSLog(@"bufferSize = %d",bufferSize);
        void* buffer= malloc(bufferSize);
    	//const void * iv = "1010101010101010";
        // Encrypt
        CCCryptorStatus ret = CCCrypt(kCCEncrypt,
                                      kCCAlgorithmAES128,
                                      kCCOptionECBMode | kCCOptionPKCS7Padding,
                                      keyPtr,
                                      kCCKeySizeAES128,
                                      NULL,
                                      plainBytes, strlen(plainBytes),
                                      buffer, bufferSize,
                                      &bytesEncrypted);
    	//verrify
    	NSLog(@"bytesEncrypte = %d",bytesEncrypted);
    	NSLog(@"plainBytes size = %d",sizeof(plainBytes));
        if (ret != kCCSuccess) {
    		NSLog(@"erreur code = %d",ret);
    		AEScipherLabel.text=@"erreur chiffrement AES";
            free(buffer);
            return nil;
        }
    	else{
    		encryptedData = [NSData dataWithBytes:buffer
    							       length:bytesEncrypted];
     
     
    		//free(buffer);
    		NSLog(@"encryptedData = %@",(NSString *)encryptedData);
    	}
     
           return encryptedData;
    }
    Je récupère la clé AES (qui est un String AESKey = "1234567891234567") du serveur (java) grâce à un message SOAP.

    et le chiffrement se fait de cette manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    NSString keyString = [NSString stringWithFormat:@"%s",AESKey];
    NSString * plainText = @"bonjour je m'appelle Olivier";
    	NSData * data= nil;
     
    	data = [self EncryptString:plainText key:keyString];

  8. #8
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
     
    @implementation NSString(Crypt)
     
    - (NSData *)encryptWithKey:(NSString *)keyString error:(NSError **)outError 
    {
        char keyPtr[kCCKeySizeAES128+1];
        [keyString getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSASCIIStringEncoding];
     
    	return [self encryptWithKeyPtr:keyPtr error:outError] ;
    }
     
     
    - (NSData *)encryptWithKeyPtr:(const char *)keyPtr error:(NSError **)outError 
    {
        if (([self length] == 0) || (strlen(keyPtr) != kCCKeySizeAES128)) {
            return nil;
    	}
     
    	NSData * encryptedData = nil;
     
        size_t bytesEncrypted = 0;
        size_t bufferSize = [self length] + kCCBlockSizeAES128 + 1;
        void* buffer= malloc(bufferSize);
    	if (buffer == NULL) return nil ;
     
    	const char *plainBytes = [self cStringUsingEncoding:NSUTF8StringEncoding] ;
        CCCryptorStatus ret = CCCrypt(kCCEncrypt,
                                      kCCAlgorithmAES128,
                                      kCCOptionECBMode | kCCOptionPKCS7Padding,
                                      keyPtr,
                                      kCCKeySizeAES128,
                                      NULL,
                                      plainBytes, strlen(plainBytes),
                                      buffer, bufferSize,
                                      &bytesEncrypted);
     
        if (ret == kCCSuccess) {
    		encryptedData = [NSData dataWithBytes:buffer length:bytesEncrypted];
    	}
    	else {
    		if (outError != nil)
    			*outError = [NSError errorWithDomain:NSPOSIXErrorDomain code:ret userInfo:nil] ;
    	}
    	free(buffer);
     
    	return encryptedData;
    }
     
    @end
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    @implementation NSData(Crypt)
     
    - (NSString *)decryptWithKey:(NSString *)keyString error:(NSError **)outError
    {
    	char keyPtr[kCCKeySizeAES128+1];
        [keyString getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSASCIIStringEncoding];
     
    	return [self decryptWithKeyPtr:keyPtr error:outError] ;
    }
     
    - (NSString *)decryptWithKeyPtr:(const char *)keyPtr error:(NSError **)outError 
    {
        if (([self length] == 0) || (strlen(keyPtr) != kCCKeySizeAES128)) {
            return nil;
    	}
     
    	NSString *decryptedString = nil;
     
    	size_t bytesDecrypted = 0;
        size_t bufferSize = [self length] + kCCBlockSizeAES128 + 1;
        void* buffer= malloc(bufferSize);
    	if (buffer == NULL) return nil ;
     
    	CCCryptorStatus ret = CCCrypt(kCCDecrypt,
                                      kCCAlgorithmAES128,
                                      kCCOptionECBMode | kCCOptionPKCS7Padding,
                                      keyPtr,
                                      kCCKeySizeAES128,
                                      NULL,
                                      [self bytes], [self length],
                                      buffer, bufferSize,
                                      &bytesDecrypted);
        if (ret == kCCSuccess) {
    		((char *)buffer)[bytesDecrypted] = '\0' ;
    		decryptedString = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];
    	}
    	else {
    		if (outError != nil)
    			*outError = [NSError errorWithDomain:NSPOSIXErrorDomain code:ret userInfo:nil] ;
    	}
    	free(buffer);
     
    	return decryptedString;
    }
     
    @end
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    int main (int argc, const char * argv[]) {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
     
    	NSData *d = [@"bonjour je m'appelle Olivier" encryptWithKey:@"1234567890123456" error:nil] ;
    	NSLog(@"%@",d) ;
    	[d writeToFile:@"/tmp/encrypted.data" atomically:NO] ;
     
    	NSLog(@"%@",[d decryptWithKey:@"1234567890123456" error:nil]) ;
     
        [pool drain];
        return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Running…
    2011-09-30 21:00:53.673 CCrypt[43749:a0f] <1a2c4dc7 e5a74696 ee0e9869 af56b37f d6714ffa ce15ca89 4eb68818 441430c6>
    2011-09-30 21:00:53.675 CCrypt[43749:a0f] bonjour je m'appelle Olivier
    et le Java :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    	public static void main(String[] args) throws Exception
    	{
    		byte[] key = "1234567890123456".getBytes();
    		SecretKey sk = new SecretKeySpec(key,"AES");
    		Cipher decrypt = Cipher.getInstance("AES/ECB/PKCS7Padding");
    		decrypt.init(Cipher.DECRYPT_MODE,sk);
     
    		FileInputStream fin =  new FileInputStream("/tmp/encrypted.data");
    		int size = fin.available() ;
    		byte[] cryptedContent = new byte[size] ;
    		fin.read(cryptedContent) ;
     
    		byte[] decryptedContent = decrypt.doFinal(cryptedContent);	
    		String decryptedMessage = new String(decryptedContent) ;
     
    		System.out.println(decryptedMessage) ;
    	}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    bonjour je m'appelle Olivier

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    ingénieur d'études
    Inscrit en
    Juillet 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2011
    Messages : 36
    Points : 29
    Points
    29
    Par défaut
    Salut,

    Merci pour ton aide, le code que tu m'as donné fonctionne très bien.

  10. #10
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2011
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 1
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Le code marche très bien en Objective C mais je souhaiterais le déchiffrer en PHP.
    Après plusieurs tests, je suis bloquée.
    En PHP, j'utilise MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB mais par exemple rien que pour l'IV je ne sais pas quoi mettre (mcrypt_create_iv).
    Je ne trouve pas son équivalent en Objective C dans le code.

    Autre question, existe-t-il un équivalent de la fonction base64encode en Objective C ?

    Je vous remercie d'avance pour votre aide.

  11. #11
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par olivpepette Voir le message
    Salut,

    Merci pour ton aide, le code que tu m'as donné fonctionne très bien.
    "très bien" : non, il faut une petite correction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	char keyPtr[kCCKeySizeAES128+1];
     
    	strncpy(keyPtr, [keyString cStringUsingEncoding:NSASCIIStringEncoding], kCCKeySizeAES128) ;
    	keyPtr[kCCKeySizeAES128] = '\0' ;
    car getCString ne garantit pas que la chaîne se termine par '\0'
    à changer dans les méthodes qui reçoivent la clé en "(NSString *)keyString".

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Decryptage fichier clé AES entre PHP et Java
    Par Gaspard22 dans le forum Sécurité
    Réponses: 0
    Dernier message: 13/04/2015, 17h24
  2. java.lang.Object javax.media.Buffer.getData()
    Par keil dans le forum Multimédia
    Réponses: 3
    Dernier message: 28/07/2011, 13h41
  3. Dialogue entre Java et Objective C
    Par Battant dans le forum Général Java
    Réponses: 4
    Dernier message: 04/04/2011, 11h48
  4. [Eclipse 3.1]conflict de path entre java Eclipse et Oracle
    Par makohsarah dans le forum Eclipse Java
    Réponses: 5
    Dernier message: 10/04/2005, 01h07
  5. [Débutant] java.lang.object
    Par bonnefr dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 27/05/2004, 14h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo