Je suis dans une discussion à travailler sur la façon de sécuriser les informations sensibles (par exemple des mots de passe) stockées dans un programme Java. Par les exigences de sécurité, de mémoire contenant des informations sensibles est désactivée, par exemple en fixant les valeurs des octets à tous les zéros. Le souci est qu'un attaquant peut observer la mémoire associés au processus de demande, et nous voulons donc de limiter autant que possible la fenêtre de temps de telles informations sensibles traîne. Auparavant, les projets C++, donc un memset() suffit.
(Incidemment, l'utilisation de memset() a été appelée en cause par certains compilateurs sont connus pour optimiser l'utilisation de l'exécutable résultant basée sur l'hypothèse que, puisque la mémoire n'est pas utilisée plus tard, il n'est pas nécessaire à zéro dans la première place. Ce texte de présentation est un avertissement pour ceux qui Google pour "memset" et "effacer la mémoire", etc).
Maintenant que nous avons sur nos mains un projet Java étant pressé contre cette exigence.
Pour les objets Java, ma compréhension, c'est que:
- un entaché de nullité de référence ne change la valeur de la référence; la mémoire sur le tas pour l'objet contient encore des données
- un objet immuable comme la Chaîne ne serait pas en mesure d'avoir des données modifiées (ou du moins pas facilement, dans les limites d'une machine virtuelle avec de bien activé dans le gestionnaire de sécurité)
- la génération éboueurs peut faire des copies d'objets de tous sur la place (comme indiqué ici)
Et pour les primitives, ma compréhension, c'est que:
- une primitive de type variable locale de la méthode sont alloués sur la pile, et:
- lorsque vous modifiez une valeur, de le modifier directement dans la mémoire (par opposition à l'aide d'une référence à manipuler un objet sur le tas).
- copies/serait faite "derrière les coulisses", dans certaines situations, comme en passant, comme un argument en méthodes ou de boxe (automatique ou non) la création des instances de l'emballage, qui contient une autre primitive variable contenant la même valeur.
Mon collègue affirme que Java primitives sont immuables et qu'il y a de la documentation à partir à la fois de la NSA, et Oracle à propos de l'absence de soutien en Java pour répondre à cette exigence.
Ma position est que les primitives peuvent (au moins dans certains cas) être remis à zéro par le réglage de la valeur à zéro (ou booléen à false), et la mémoire est effacée de cette façon.
Je suis en train de vérifier s'il y a dans la langue dans la JLS ou autres "officiel" de la documentation sur le comportement requis de Jvm quand il s'agit de la gestion de la mémoire à l'égard de primitives. Le plus proche que j'ai pu trouver était "Sûr des Directives de Codage pour le Langage de Programmation Java" sur Oracle site qui mentionne la compensation des tableaux de char après utilisation.
J'avais chipoter sur des définitions lorsque mon collègue appelées primitives immuable, mais je suis sûr qu'il voulait dire "la mémoire ne peut pas être correctement remis à zéro" - nous allons vous inquiétez pas à ce sujet. Nous n'avons pas à discuter si il voulait final variables de contexte, on parlait en général.
Existe-il des réponses définitives ou des références à ce sujet? Je te remercie de tout ce qui pourrait me montrer où je me trompe ou confirmer que j'ai raison.
Edit: Après réflexion, j'ai été en mesure de préciser que mon collègue a été pensée de la primitive wrappers, pas les primitifs eux-mêmes. Donc on se retrouve avec le problème de comment libérer de la mémoire en toute sécurité, de préférence des objets. Aussi, pour clarifier, les informations sensibles ne sont pas juste des mots de passe, mais aussi des choses comme des adresses IP ou des clés de chiffrement.
Y a-commercial machines virtuelles qui offrent une fonctionnalité comme une priorité à la manipulation de certains objets? (J'imagine que ce serait en fait violer la Java spec, mais j'ai pensé que je demanderais juste au cas où je me trompe.)