Gebruik char Array Over a String voor het manipuleren van wachtwoorden in Java?

1. Overzicht

In dit artikel leggen we uit waarom we char [] array voor het weergeven van wachtwoorden in plaats van Draad in Java.

Houd er rekening mee dat deze tutorial zich richt op de manieren om wachtwoorden in het geheugen te manipuleren, niet op de daadwerkelijke manieren om ze op te slaan, die meestal wordt afgehandeld in de persistentielaag.

We gaan er ook van uit dat we het formaat van het wachtwoord niet kunnen controleren (het wachtwoord komt bijvoorbeeld van de API van derden in de vorm van de Draad). Hoewel het voor de hand ligt om een ‚Äč‚Äčtype object te gebruiken java.lang.String voor het manipuleren van wachtwoorden, wordt het door het Java-team zelf aanbevolen om te gebruiken char [] in plaats daarvan.

Als we bijvoorbeeld kijken naar de JPasswordField van javax.swing, kunnen we zien dat de methode getText () die terugkeert Draad is verouderd sinds Java 2 en wordt vervangen door haal wachtwoord op() methode die terugkeert char [].

Laten we dus een paar sterke redenen onderzoeken waarom dat het geval is.

2. Snaren zijn onveranderlijk

Draads in Java zijn onveranderlijk, wat betekent dat we ze niet kunnen wijzigen met behulp van API's op hoog niveau. Elke wijziging op een Draad object zal een nieuw Draad, de oude in het geheugen bewaren.

Daarom is het wachtwoord opgeslagen in een Draad zal beschikbaar zijn in het geheugen totdat Garbage Collector het wist. We hebben geen controle over wanneer het gebeurt, maar deze periode kan sindsdien aanzienlijk langer zijn dan voor reguliere objecten Snaren worden bewaard in een String Pool voor hergebruiksdoeleinden.

Daarom kan iedereen met toegang tot de geheugendump het wachtwoord uit het geheugen halen.

Met een char [] array in plaats van de Draadkunnen we gegevens expliciet wissen nadat we klaar zijn met het beoogde werk. Op deze manier zorgen we ervoor dat het wachtwoord uit het geheugen wordt verwijderd, zelfs voordat garbage collection plaatsvindt.

Laten we nu eens kijken naar codefragmenten, die laten zien wat we zojuist hebben besproken.

Ten eerste voor Draad:

System.out.print ("Original String wachtwoordwaarde:"); System.out.println (stringPassword); System.out.println ("Original String wachtwoord hashCode:" + Integer.toHexString (stringPassword.hashCode ())); String newString = "********"; stringPassword.replace (stringPassword, newString); System.out.print ("String-wachtwoordwaarde nadat geprobeerd is deze te vervangen:"); System.out.println (stringPassword); System.out.println ("hashCode nadat geprobeerd is de originele String te vervangen:" + Integer.toHexString (stringPassword.hashCode ()));

De output zal zijn:

Originele String-wachtwoordwaarde: wachtwoord Originele String-wachtwoord hashCode: 4889ba9b String-waarde nadat geprobeerd is deze te vervangen: wachtwoord hashCode nadat geprobeerd is de originele String te vervangen: 4889ba9b

Nu voor char []:

char [] charPassword = nieuw char [] {'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}; System.out.print ("Oorspronkelijke tekenwachtwoordwaarde:"); System.out.println (charPassword); System.out.println ("Original char wachtwoord hashCode:" + Integer.toHexString (charPassword.hashCode ())); Arrays.fill (charPassword, '*'); System.out.print ("Gewijzigde char-wachtwoordwaarde:"); System.out.println (charPassword); System.out.println ("Veranderd char wachtwoord hashCode:" + Integer.toHexString (charPassword.hashCode ()));

De output is:

Oorspronkelijke char wachtwoord waarde: wachtwoord Oorspronkelijke char wachtwoord hashCode: 7cc355be Gewijzigde char wachtwoord waarde: ******** Gewijzigde char wachtwoord hashCode: 7cc355be

Zoals we kunnen zien, hebben we geprobeerd de inhoud van het origineel te vervangen Draad, de waarde blijft hetzelfde en hashCode () methode heeft geen andere waarde geretourneerd in dezelfde uitvoering van de applicatie, wat betekent dat het origineel Draad bleef intact.

En voor de char [] array, konden we de gegevens in hetzelfde object wijzigen.

3. We kunnen per ongeluk wachtwoorden afdrukken

Een ander voordeel van het werken met wachtwoorden in char [] array is het voorkomen van onbedoeld loggen van het wachtwoord in consoles, monitoren of andere min of meer onveilige plaatsen.

Laten we eens kijken naar de volgende code:

String passwordString = "wachtwoord"; char [] passwordArray = nieuw char [] {'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}; System.out.println ("Printing String wachtwoord ->" + passwordString); System.out.println ("Printing char [] wachtwoord ->" + passwordArray);

Met de output:

Printing String wachtwoord -> wachtwoord Printing char [] wachtwoord -> [[email protected]

We zien dat de inhoud zelf in het eerste geval wordt afgedrukt, terwijl in het tweede geval de gegevens niet zo nuttig zijn, wat maakt char [] minder kwetsbaar.

4. Conclusie

In dit korte artikel hebben we verschillende redenen benadrukt waarom we deze niet zouden moeten gebruiken Draads voor het verzamelen van wachtwoorden en waarom we dit zouden moeten gebruiken char [] arrays.

Zoals altijd zijn codefragmenten te vinden op GitHub.