Η δημιουργία τυχαίων κωδικών, συνθηματικών και αλφαριθμητικών γίνεται συνήθως για χρήση τους ως συνθηματικού για τον λογαριασμό του χρήστη στον υπολογιστή μας, τα email, τα προσωπικά δεδομένα και για ότι θα θέλαμε να προστατέψουμε με ένα κωδικό.
Εισαγωγή
Η καθημερινότητα μας με την χρήση υπολογιστή και κινητών είναι γεμάτη από την ακόλουθη πρόταση:
Δημιουργήστε έναν κωδικό για τον λογαριασμό σας
Η παραλλαγές αυτής της πρότασης είναι πολλές και χρησιμοποιούνται για να μας ζητήσουν να γράψουμε μια τυχαία (μη προβλέψιμη) λέξη που αποτελείται από τυχαία γράμματα, αριθμούς και σύμβολα.
Φυσικά οι περισσότεροι τι κάνουν; Βάζουν λέξεις, ονόματα (σκύλων, μάρκας αυτοκινήτου κλπ), ημερομηνίες γέννησης, αριθμούς τηλεφωνικούς κ.α. τέτοια τα οποία είναι ήδη γνωστά σε πολλούς, μιας και τα έχουμε προσφέρει απλόχερα σε διάφορα κοινωνικά δίκτυα (όπως facebook) και μπορεί κάποιος κακόβουλος χρήστης να τα βρει με εργαλεία που είναι διαθέσιμα στο διαδίκτυο.
Για να αποφύγουμε τέτοια λάθη, συνήθως οι πιο ψαγμένοι, χρησιμοποιούν κάποιο λογισμικό που παράγει τυχαίους κωδικούς με μια γεννήτρια κωδικών και τα αποθηκεύει μόνιμα είτε στον υπολογιστή είτε στον browser μας. Οι ακόμα πιο ψαγμένοι, θα δοκιμάσουν την ισχυρότητα (το πόσο μη προβλέψιμο είναι) των κωδίκων με χρήση κάποιας υπηρεσίας που ελέγχει την αδυναμία των κωδικών που χρησιμοποιούμε, όπως είδαμε στο άρθρο «Δείτε πόσο αδύναμα είναι τα password σας«
Όλα τα παραπάνω είναι μια χαρά και κάνουν την δουλειά τους όπως πρέπει. Παρόλα αυτά, υπάρχουν 2 βασικοί λόγοι που μπορεί να θέλετε να αποφύγετε την χρήση λογισμικών για την παραγωγή τυχαίων κωδικών:
- Είστε απλά παρανοϊκός και δεν εμπιστεύεστε ούτε καν ανοιχτού κώδικα γεννήτριες τυχαίων κωδικών (Οκ… δεν μπορώ να το σχολιάσω αυτό)
- Θέλετε απλά να δημιουργήσετε έναν (ή πολλούς) με χρήση αποκλειστικά των δικών σας χεριών.
Υπάρχουν διάφορες τεχνικές που μπορείτε να χρησιμοποιήσετε μέσω τερματικού τα οποία θα μπορούν να σας δώσουν τυχαίους κωδικούς και να τα χρησιμοποιήσετε είτε ως PIN, είτε για λογαριασμούς, είτε γιατί είστε sysadmin και θέλετε κάτι στα γρήγορα και αξιόπιστα για διάφορους λόγους.
Εδώ θα δούμε μερικές απλές τεχνικές βήμα βήμα ώστε να μάθουμε 2-3 πράγματα για το τερματικό και θα έχουμε κατά νου ότι θα ασχοληθούμε με το 2. ενώ ο λόγος για τον οποίο τα θέλετε (1.) είναι δικό σας θέμα ;)
Τυχαίοι κωδικοί με βάση την Ημερομηνία-Ώρα-Λεπτά-Δευτερόλεπτα
Θα μπορούσαμε να πούμε ότι η χρονική στιγμή του «τώρα» ορίζεται από ένα αριθμό που έχει την μορφή «Ημερομηνία-Ώρα-Λεπτά-Δευτερόλεπτα«.
Σημείωση… ο ορισμός που έδωσα είναι εντελώς γενικός ορισμός και ξέρω ότι κάποιοι φυσικοί και φιλόσοφοι ανάμεσα στους αναγνώστες μας με μουντζώνουν αυτή την στιγμή, αλλά παρακαλώ δείξτε κατανόηση γιατί και εγώ προσπαθώ με νύχια και με δόντια να κρατηθώ ώστε να μην επεκταθώ σε φιλοσοφικές – επιστημονικές προεκτάσεις του τι είναι «τώρα» και πόσο μάλλον αν μπορούμε να πράξουμε πραγματικά τυχαίους κωδικούς.
Ανοίξτε λοιπόν το τερματικό σας (τι πρωτότυπο…) και μπείτε στον προσωρινό φάκελο του συστήματος /tmp (για πειράματα είναι ο κατάλληλος φάκελος) και πείτε του να σας επιστρέψει την ημερομηνία που έχετε με την εντολή date :
date Fri May 6 14:21:11 EEST 2016
Πολύ ωραία λοιπόν, μας είπε ότι την χρονική στιγμή που τρέξατε την εντολή είχε την ημερομηνία «Fri May 6 14:21:11 EEST 2016» . Ναι αλλά, μάλλον δεν θα μας βολέψει και γιαυτό τον λόγο θα τροφοδοτήσουμε (pipe με το σύμβολο | ) αυτό το αποτέλεσμα σε μια άλλη εντολή την shasum για να μας δώσει την μοναδική αλφαριθμητική εκδοχή:
date|shasum ef4761d3cb3cc248b0b748d39e6f9e45a0840f78 -
Αν τώρα θέλουμε να μειώσουμε το μέγεθος της αλφαριθμητικού αποτελέσματος, μπορούμε να ζητήσουμε π.χ. μόνο τα 8 πρώτα ψηφία. Για να το κάνουμε αυτό επανα-τροφοδοτούμε το αποτέλεσμα της φόρμουλας στην ενδολή head και του λέμε «φέρε μου 8 στοιχεία».:
date|shasum|head -c 8d2b0a6cd %
Ωραία… όπως βλέπετε είναι 8 ψηφία αλλά διαφορετικά από το προηγούμενο αποτέλεσμα… γιατί όμως δεν είναι ef4761d3 και είναι 8d2b0a6cd ;
Τυχαίο ;… Δεν νομίζω Τάκη…
Η απάντηση είναι απλή. Εδώ εκμεταλλευόμαστε το γεγονός ότι κάθε χρονική στιγμή, επειδή αλλάζουν τα δευτερόλεπτα, θα είναι μοναδικό το αποτέλεσμα του shasum.
Φυσικά αν τρέξετε την παραπάνω «φόρμουλα» 5 φορές στο ίδιο δευτερόλεπτο, το αποτέλεσμα θα είναι ίδιο (οι κωδικοί θα είναι ίδιοι). Ας το δοκιμάσουμε λοιπόν να δούμε αν ισχύει. Για να το κάνουμε αυτό θα χρησιμοποιήσουμε μια συνθήκη στην οποία θα ζητήσουμε από το σύστημά μας να τρέξει την εντολή 5 φορές. Δηλαδή το κάθε ένα από τα αποτελέσματα (5 στον αριθμό) θα προκύπτει από την ίδια εντολή.
for apotelesma in `seq 1 5`; do date | shasum | head -c 8; echo ""; done a95e2152 a95e2152 a95e2152 a95e2152 a95e2152
Τι έγινε τώρα… κάποιοι με χάσατε… Ας δούμε τον κώδικα μας βήμα βήμα (ω ναι μόλις γράψατε κώδικα προγραμματισμού σε bash):
- for apotelesma in `seq 1 5`; Εδώ λέμε: Για κάθε αποτέλεσμα από το 1 έως το 5
- do date | shasum | head -c 8; Εδώ λέμε: δώσε μου την ημερομηνία σε μορφή shasum αλλά μόνο τα 8 πρώτα ψηφία
- echo «»; Εδώ λέμε: μετά από το αποτέλεσμα στο κάθε ένα , βάλε και μια νέα γραμμή για να μην είναι κολλημένα το ένα δίπλα στο άλλο.
- done Εδώ λέμε: να σταματήσεις μόλις τελειώσεις την εργασία (1 έως 5 φορές)
Φαντάζομαι τώρα θα έγινε πιο κατανοητό το τι κάναμε έτσι;
Χρονοκαθηστέριση
Όπως βλέπετε από το αποτέλεσμα, η κάθε γραμμή είναι ίδια με την προηγούμενη. Αν όμως, για κάποιον λόγο καθυστερήσει η διεργασία, π.χ. στο 3 από τα 5 κάποια άλλη διεργασία του λειτουργικού έχει προτεραιότητα στους πόρους του συστήματος και αντί να εκτελεστούν σε ένα δευτερόλεπτο, εκτελεστούν σε 2-3 τότε μπορεί να δείτε διαφορετικούς κωδικούς.
Χμμμ… καλή ιδέα αυτό… ας το εκμεταλλευτούμε. Έστω ότι θέλουμε να δημιουργήσουμε 5 τυχαίους διαφορετικούς κωδικούς με την ίδια φόρμουλα μας και χρησιμοποιώντας τον ίδιο κώδικα. Για να το κάνουμε αυτό θα προσθέσουμε μια καθυστέρηση στην εκτέλεση κάθε βήματος. Με άλλα λόγια θα πούμε στο σύστημά μας να περιμένει 1 δευτερόλεπτο πριν πάει στο επόμενο από τα 5 βήματα. Αυτό το κάνουμε με την εντολή sleep και την παράμετρο 1 (δευτερόλεπτο):
for apotelesma in `seq 1 5`; \ do \ date | shasum | head -c 8; \ echo ""; \ sleep 1; \ done f0b3a8dd b13abfee febbe970 b33d07de e094ff0c
Ωραία, τώρα έχουμε το αποτέλεσμα που θέλαμε.
Οι πιο παρατηρητικοί ανάμεσα μας θα δουν ότι μοιάζει διαφορετικός ο κώδικας αυτή την φορά, ενώ στην πραγματικότητα είναι ίδιος απλά αντί να έχω μια μακροσκελής εντολή (που δεν βγάζει νόημα) την «έσπασα» σε γραμμές ώστε να αντιπροσωπεύει τον τρόπο με τον οποίο θα το γράφαμε σε κώδικα όπως είπαμε στο άρθρο με τις καλές πρακτικές για τις μακροσκελείς εντολές.
Μετατροπή σε πρόγραμμα
Μιας και φτάσατε μέχρι εδώ και ήδη έχετε γράψει κώδικα για δημιουργία τυχαίων κωδικών με βάση το «τώρα», είναι καλή ιδέα να το μετατρέψουμε σε μικρό πρόγραμμα μιας και είναι βαρετό και ανούσιο κάθε φορά να γράφετε όλο αυτό για μερικούς κωδικούς. Τι λέτε;
Μην τρομάζετε με την ιδέα διότι έχετε ήδη γράψει τον «πυρήνα» του προγράμματος χωρίς ίσως να το καταλάβετε :)
Για να το μετατρέψουμε σε πρόγραμμα θα χρειαστεί να κάνουμε τα παρακάτω βήματα:
- Να το γράψουμε σε ένα κειμενογράφο (π.χ. gedit, vi, nano, leafpad κλπ) και να το αποθηκεύσουμε σε αρχείο
- Να μεταφέρουμε το αρχείο σε σημείο του συστήματος που θα ανήκει στις διαδρομές των εκτελέσιμων προγραμμάτων του τερματικού
- Να το μετατρέψουμε σε εκτελέσιμο λογισμικό.
Πάμε λοιπόν βήμα βήμα.
Ο κώδικας
Ανοίγουμε τον κειμενογράφο μας και στην αρχή γράφουμε την παρακάτω γραμμή :
#!/usr/bin/env sh
Με την παραπάνω γραμμή, λέμε στο σύστημά μας ότι το περιβάλλον το οποίο θα αναλάβει να εκτελέσει τον κώδικα με τις οδηγίες μας θα είναι το κέλυφος (τερματικό περιβάλλον).
Έπειτα, γράφουμε τις οδηγίες μας και το τι θέλουμε να κάνει το κέλυφος όταν εκτελούμε το πρόγραμμά μας:
#!/usr/bin/env sh
for apotelesma in `seq 1 5`
do
date | shasum | head -c 8
echo ""
sleep 1
done
Ωραία, αφού το γράψετε, οπτικά θα φαίνεται όπως στην παρακάτω εικόνα :

Μπορείτε να κλείσετε τον κειμενογράφο και αποθηκεύσετε το αρχείο με όποιο όνομα θέλετε το οποίο όνομα θα είναι και το όνομα του προγράμματος που φτιάξατε. Εγώ επέλεξα να το πω «kodmera» συνδυάζοντας την λέξη κωδικός και ημέρα για να το θυμάμαι εύκολα.
Μπορείτε να κατεβάσετε τον προγραμματάκι με τον κώδικά από το αποθετήριο λογισμικών του Cerebrux
Μεταφορά του αρχείου στον φάκελο προγραμμάτων
Το επόμενο βήμα είναι να το μεταφέρουμε στον φάκελο προγραμμάτων του Linux για να μπορούμε να το εκτελούμε όποτε θέλουμε χωρίς να χρειάζεται να δίνουμε και την διαδρομή του. Ναι αλλά που είναι αυτός ο φάκελος ;
Βασικά δεν υπάρχει ένας μόνο φάκελος προγραμμάτων :) Χωρίς να μπούμε τώρα σε λεπτομέρειες γιατί γίνεται αυτό μπορείτε να δείτε τους φακέλους απο τους οποίους «βλέπει» τα εκτελέσιμα προγράμματα το κέλυφός σας δίνοντας την εντολή $PATH:
$PATH bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:
Όπως βλέπετε, είναι αρκετοί φάκελοι (χωρίζονται με : ). Συνήθως για τα προγράμματα που φτιάχνουμε εμείς, τα βάζουμε στον φάκελο /usr/bin ή /usr/local/bin. Οπότε πάμε να μετακινήσουμε με την εντολή mv το πρόγραμμα μας υποθέτοντας ότι επεξεργαστήκατε και έχετε αποθηκεύσει το αρχείο στον φάκελο /tmp.
sudo mv kodmera /usr/local/bin/
Εκτελέσιμο πρόγραμμα
Το τελευταίο μας βήμα είναι να κάνουμε εκτελέσιμο το πρόγραμμά μας και φυσικά να το τρέξουμε. Υποθέτοντας οτι το μετακινήσαμε στον φάκελο /usr/local/bin/ προσθέτουμε την εκτελέσιμη ιδιότητα στο πρόγραμμά μας:
sudo chmod +x /usr/local/bin/kodmera
Ας το τρέξουμε τώρα:
kodmera 33533f42 a475f388 de26598e b6e08c0e 0a02dfd1
Τέλεια ! Το πρόγραμμα μας δουλεύει. Μπορούμε πλέον, κάθε φορά που θα χρειαζόμαστε, στα γρήγορα, μερικούς τυχαίους κωδικούς να εκτελούμε το πρόγραμμά μας.
Επίλογος
Ίσως να φάνηκαν πολλά μαζεμένα, ελπίζω όμως να ήταν εποικοδομητικό. Μάθαμε μερικές χρήσιμες εντολές:
- date
- shasum
- head
- sleep
- $PATH
- chmod
- Γράψαμε το πρόγραμμά μας σε κώδικα Shell Scripting
Στο επόμενο άρθρο, θα χρησιμοποιήσουμε μια συσκευή του πυρήνα Linux για παραγωγή τυχαίων κωδικών.
Πολύ ωραίο ως εκπαιδευτική άσκηση, αλλά στην πράξη υπάρχουν έτοιμα εργαλεία όπως το pwgen που κάνουν τη δουλειά σωστά, εύκολα και παραμετροποιήσιμα.
Συμφωνώ, το pwgen είναι εξαιρετικό !. Στόχος ήταν να μάθουμε μερικά πράγματα από αυτή την διαδικασία για όσους ανήκουν στην 2η κατηγορία χρηστών.
Το apg (π.χ. apg -m 10 -x 12 -l -M NCLS) άλλο ένα και έρχεται με το κουτί, νομίζω.
Yeap ! είναι προεγκατεστημένο και πολύ χρήσιμο.
Βλέπω πως αυτό είναι το πρώτο μέρος του μαθήματος, και νομίζω πως θα το καλύψεις το συγκεκριμένο στο επόμενο.
Αλλα νιώθω πως το συγκεκριμένο είναι κακή πρακτική για δημιουργεία κωδικών, γιατί θεωριτικά είναι sequential και όχι πραγματικά τυχαία, σαν κώδικα θα πρέπει να δίξεις κάτι βασισμένο σε random αλγόριθμο.
Βιάζεσαι :) Είναι στο επόμενο …
Στόχος ήταν όπως είπα, να χρησιμοποιήσουμε μερικά εργαλεία που ενώ η βασική τους χρήση είναι για άλλο σκοπό (date, shasum κλπ) εμείς τα χρησιμοποιούμε για με συνδυασμούς (piping) και μαθαίνουμε και λίγο bash scripting. Απέφυγα να μιλήσω για «ασφάλεια» μιας και θα έγραφα σελίδες εστιάζοντας στο δέντρο και θα έχανα το δάσος.
Υπάρχει κάποιος λόγος που βάζεις shebang ‘/usr/bin/env sh’ ;
Ναι σωστή παρατήρηση ! Κανένας σοβαρός λόγος. Ειδικά σε τόσο μικρά script είτε χρησιμοποιήσεις καρφωτά την διαδρομή για κάποιο κέλυφος είτε έτσι, δεν παίζει κανέναν ρόλο.
Μιας που το ειδα σημερα, το NTP φτιαχνει random κλειδια (/etc/ntp.keys) με την παρακατω εντολη:
tr -dc ‘[:alnum:]’ < /dev/urandom | head -c 20
pseudorandom : https://bit.ly/3fT0PFN