8
votes

Simulation d'un chiffre d'écoute avec AES / CTR

J'écris un serveur d'applications et j'ai décidé d'utiliser AES128 / CTR / NOPADDIND pour sécuriser les connexions, car il est considéré comme suffisant sans avoir à élargir les octets à la limite de bloc et je pensais que c'est un bon ajustement TCP qui est logiquement un flux transparent.

Le problème est que Ciphher.Unupdate () ne renvoie pas le bloc crypté jusqu'à ce qu'il ait un bloc de 16 octets complet, car le CTR est fondamentalement basé sur un chiffrement à blocs, cependant de simuler un chiffre d'essence. Je devrais lire des données à partir d'une prise TCP et des messages de traitement de TCP dès leur arrivée, mais je ne peux pas récupérer le bloc le plus récent, car il se développe toujours et sa taille est inférieure à 16 octets. Et je ne peux pas attendre parce que nous ne savons pas quand le prochain message serait envoyé. Bien sûr, je pourrais appeler cipher.dofinal () pour obtenir le reste, mais cela signifierait la fin du flux (connexion) et l'objet de chiffrement serait réinitialisé.

Je pensais que ce serait bien s'il ya un moyen de regarder le report. CTR XORS XORS Le texte brut avec la touche de frappe afin que je puisse être capable d'obtenir les données cryptées quel que soit le reste des octets du bloc. Y aurait-il une bonne solution de contournement à ce problème? Je pense à écrire un wrapper qui crypte de faux texte brut avec des zéros pour obtenir la touche à l'avance et Xors manuellement, mais je me demande comment les autres ont résolu ce problème.

mise à jour

Je développe une application Android et je suis avéré que c'est le problème du Dalvik VM. Comme Robert et Monnand ont souligné ci-dessous, Java SE n'a pas ce problème au moins avec le fournisseur par défaut. Je pense que je vais devoir écrire une classe wrapper ou changer le mode en CFB8 pour contourner ce problème. (CTR8 n'a pas fonctionné) Merci pour toutes les réponses!


4 commentaires

Pouvez-vous donner des messages de sorte que leur longueur soit un multiple de 16? Cela garantirait que vous vous retrouvez toujours avec un morceau déchifftable.


@Chris: Merci pour la suggestion, cela pourrait être une solution possible. Mais j'aimerais éviter que si possible, car il n'est pas préférable en termes d'efficacité du réseau, bien que cela puisse être négligeable.


Vous pouvez simplement appeler cela sur un tableau composé de zéros pour obtenir la touche de frappe. Puis xor il manuellement dans votre message.


Java SE n'a pas ce problème car il ne prend pas en charge AES128 / CTR / NOPADDING du tout, au moins avec le fournisseur par défaut. Je viens d'essayer, Java 7 Oracle (mais j'ai peut-être été mélangée et j'utilise OpenJDK, tout est possible).


3 Réponses :


0
votes

Je n'ai pas eu à résoudre ce problème moi-même, mais une solution de contournement serait de produire le flux de clé manuellement et de gérer le xoring vous-même.

C'est-à-dire que vous allez passer de AES / CTR / NOPADDING à AES / ECB / NOPADDING et crypté à plusieurs reprises votre Incrémentation de la valeur de compteur , chaque fois que vous avez besoin de données fraîches sur XOR avec le CIPHERText.

loin de l'idéal, mais je suppose que cela fonctionnerait.


1 commentaires

Merci pour la suggestion. Je pense que je peux utiliser CTR avec un tableau de zéros pour obtenir le clavier.



5
votes

Je viens de tester les AES en mode CTR à l'aide d'Oracle Java 1.7 et je ne peux pas vérifier vos observations: xxx

peut être une implémentation de tiers défectueux car "AES128 / CTR / NOPADDING" n'est pas un chiffre connu sur mon système.


1 commentaires

Vous avez raison, c'était le problème de l'Android Dalvik VM, pas de Java SE.



4
votes

J'avais exactement le même problème aujourd'hui et j'ai été réparé juste maintenant.

Le problème est votre fournisseur, qui est probablement Castle Bouncy . Lorsque vous appelez getinstance () code>, il suffit de fournir le nom de votre algorithme (qui dans mon cas est "AES / CTR / NOPADDING"). ne pas strong> Spécifiez le fournisseur. p>

laissez le code expliquer lui-même: p>

comme @robert indiqué, le code suivant fonctionne correctement: P>

Cipher c = Cipher.getInstance("AES/CTR/NoPadding", "BC");
KeyGenerator kg = KeyGenerator.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, kg.generateKey());
System.out.println(c.update(new byte[20]).length); // output: 16
System.out.println(c.update(new byte[1]).length);  // null pointer exception


3 commentaires

Dans mon cas, Android Dalvik était le problème, mais merci d'avoir souligné qu'un fournisseur personnalisé a également le même problème.


Merci de me laisser savoir que Android a le même problème (fonctionnalité?). Ceci est gênant puisqu'un avantage du mode de comptoir est qu'il peut être utilisé sans rembourrage.


Je sais que cette question est de quelque temps ... la question est-elle toujours présente dans une source de la Colombie-Britannique moderne?