{"id":1099,"date":"2018-06-11T01:53:35","date_gmt":"2018-06-10T23:53:35","guid":{"rendered":"http:\/\/hobbykeller.spdns.de\/?p=1099"},"modified":"2020-01-26T18:45:15","modified_gmt":"2020-01-26T17:45:15","slug":"itan-listen-mit-hilfe-von-ocr-einlesen","status":"publish","type":"post","link":"https:\/\/hobbykeller.spdns.de\/?p=1099","title":{"rendered":"iTAN Listen mit Hilfe von OCR einlesen"},"content":{"rendered":"<figure id=\"attachment_1100\" aria-describedby=\"caption-attachment-1100\" style=\"width: 220px\" class=\"wp-caption alignleft\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1100 size-full\" src=\"http:\/\/hobbykeller.spdns.de\/wp-content\/uploads\/2018\/06\/220px-Tanliste.jpg\" alt=\"\" width=\"220\" height=\"160\" \/><figcaption id=\"caption-attachment-1100\" class=\"wp-caption-text\"><a href=\"https:\/\/commons.wikimedia.org\/wiki\/File:Tanliste.jpg\" target=\"_blank\" rel=\"noopener noreferrer\">Quelle: CC BY-SA 3.0<\/a><\/figcaption><\/figure>\n<p>Obgleich die iTAN als Auslaufmodell gilt, schicken viele Finanzinstitute ihren Kunden weiterhin solche Listen als &#8220;fall back&#8221;, wenn moderne Verfahren scheitern. Meine Hausbank versendet solche Listen in einem Format, das in 6 Spalten mit jeweils 20 Zeilen insgesamt 120 numerierte TANs enth\u00e4lt. Wer diese iTANs in einen anerkannten Passwort-Manager wie z.B. <a href=\"https:\/\/www.keepassx.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">KeePassX<\/a> \u00fcbertragen m\u00f6chte, dem steht jede Menge Abtipp-Arbeit bevor. Wer jedoch ein wenig Ehrgeiz an den Tag legt, dem gelingt das automatisierte Einlesen per OCR erstaunlich gut.<!--more--><\/p>\n<p>[alert type=&#8221;warning&#8221; icon-size=&#8221;normal&#8221;]Einge Finanzinstitute untersagen die \u00dcbertragung der iTANs in Passwort-Manager selbst dann, wenn diese Manager die Daten mit anerkannten Verfahren verschl\u00fcsseln und getrennt von der Telebanking-PIN abgespeichern. Vor Anwendung dieser Methode sollte jeder Nutzer die AGBs seiner Bank genau studieren.[\/alert]<\/p>\n<h1>1. Grafische Bedienoberfl\u00e4chen vs. Konsole<\/h1>\n<p>Ich habe jede Menge grafische Bedienoberfl\u00e4chen durchprobiert &#8211; Ergebnis: Alle Resultate waren bislang unzureichend. Nachdem ich das leidige OCR-Thema lange Zeit ruhen gelassen habe, bin ich durch Zufall auf <a href=\"https:\/\/www.howtoforge.com\/tutorial\/tesseract-ocr-installation-and-usage-on-ubuntu-16-04\/\" target=\"_blank\" rel=\"noopener noreferrer\">eine Anleitung<\/a> gesto\u00dfen, bei der ausschlie\u00dflich mit Konsolenbefehlen gearbeitet wird, die sich sogar zu einem Script zusammenfassen lassen, das es erlaubt, eine iTAN Liste innerhalb weniger Sekunden zu scannen und als ASCII Text auszugeben.<\/p>\n<p>Erforderlich sind dazu im wesentlichen die Programmpakete Tesseract und Imagemagick, die sich problemlos unter Ubuntu installieren lassen.<\/p>\n<h1>2. Kochrezept zur Umwandlung der iTAN-Liste in eine Scan-Vorlage<\/h1>\n<h2>2.1 Scannen der Liste<\/h2>\n<p class=\"\">Es empfiehlt sich die Liste mittels des <code>scanimage<\/code> Kommandos im Grauformat mit einer Aufl\u00f6sung von mindestens 300 dpi zu erfassen und im <code>pnm<\/code>-Format (portable network map) abzuspeichern.<\/p>\n<p>Gleichzeitig kann der gesamte Scanbereich bereits durch die Parameter <code>t<\/code>, <code>l<\/code>, <code>x<\/code> und <code>y<\/code> eingegrenzt werden, so dass keine unn\u00f6tigen Leerfl\u00e4chen und Spaltenbeschriftungen erfasst werden. Dieses Kommando sieht bei mir wie folgt aus:<\/p>\n<pre class=\"lang:default decode:true\" title=\"Scanning the list\">scanimage --device 'xerox_mfp:libusb:002:004' --format=pnm --mode 'Gray' --resolution 300 -l 6 -t 6 -y 74 -x 170  &gt; scan.pnm\r\n<\/pre>\n<p>Zur exakt waagerechten Ausrichtung der Zeilen wird h\u00e4ufig noch empfohlen, das gescannte Bild mit dem <code>unpaper<\/code> Befehl entsprechend auszurichten. Da die Scanvorlage jedoch ohnehin schon pr\u00e4zise auf dem Scannerglas liegt, ist dieser Schritt m.E. im konkreten Anwendungsfall entbehrlich. Ebenfalls nicht erforderlich ist es, das Bild mittels des <code>convert<\/code> Befehls aus dem imagemagick Paket in ein Graustufenbild umzuwandeln &#8211; der <code>scanimage<\/code> Befehl hat dies ja bereits durch den Parameter <code>--mode 'Gray'<\/code> bewirkt.<\/p>\n<h2>2.2 Vergr\u00f6\u00dfern<\/h2>\n<p>Die zuvor erw\u00e4hnte Anleitung von howtoforge.com weist darauf hin, dass sich die Treffsicherheit der Tesseract OCR Software erheblich erh\u00f6ht, wenn man zuvor das gesacnnte Bild vergr\u00f6\u00dfert:<\/p>\n<blockquote><p>Resizing is one of the most helpful tricks to improve OCR accuracy. This is because most of time images, have very small font size which cannot be read properly by Tesseract.<\/p><\/blockquote>\n<p>Dies l\u00e4sst sich durch den <code>convert<\/code> Befehl des Imagemagick-Paketes erreichen. Gleichzeitig verwandeln wir das gescannte Bild in ein <code>png<\/code>-Format.<\/p>\n<pre class=\"lang:default decode:true \" title=\"Enlarging the scan\">convert -resize 150% scan.pnm scan.png\r\n<\/pre>\n<h2>2.3 Umwandlung in ein bin\u00e4res (schwarz-wei\u00df) Bild<\/h2>\n<p>Oftmals erfolgt bereits in den vorherigen Schritten die Empfehlung, das Bild gleich als TIF-Format abzuspeichern, so dass eine reine schwarz-wei\u00df-Vorlage entsteht, die Tesseract besser verarbeiten kann. Dies w\u00fcrde jedoch zu unerw\u00fcnschten Resultaten f\u00fchren, da sich bei der TIF-Erzeugung kein individueller Schwellwert eingeben l\u00e4sst, ab wann ein Bildpunkt als Schwarz oder wei\u00df gelten soll. W\u00e4hrend die Lesbarkeit der Liste f\u00fcr einen Menschen erh\u00f6ht wird, wenn jede 2. Zeile mit einem grauen Hintergrund hinterlegt ist, verh\u00e4lt es sich bei der TIF-Erzeugung genau umgekehrt: Die Buchstaben verschwimmen mit dem grauen Hintergrund.<\/p>\n<p>Der <code>convert<\/code> Befehl erlaubt es, mit Hilfe eines sinnvoll gew\u00e4hlten Schwellwertes (in meinem Fall 30%) den grauen Hintergrund in jeder 2. Zeile der Liste fast vollst\u00e4ndig herauszufiltern.<\/p>\n<pre class=\"lang:default decode:true\" title=\"Producing a binary image\">convert scan.png -threshold 30% scanbin.png\r\n<\/pre>\n<h2>2.4 Ausschneiden der Spalten mit den iTANs<\/h2>\n<p>Neben der grauen Hinterlegung von Zeilen oder Spalten, kann die iTAN Liste noch weitere Elemente enthalten, die sich f\u00fcr die maschinelle Texterkennung als hinderlich erweisen. Dazu geh\u00f6ren in meinem Fall vertikale Linien, die die einzelnen Spalten trennen.<\/p>\n<p>Ich schneide daher aus der iTAN-Liste die 6 Spalten mit den nackten iTANs (ohne irgendwelche Trennlinien und auch ohne die vorangehende Numerierung) aus. Die Numerierung wird sp\u00e4ter mit Hilfe des <code>awk<\/code>-Kommandos hinzugef\u00fcgt.<\/p>\n<pre class=\"lang:default decode:true\" title=\"Cutting, converting and numbering\">for i in $(seq 0 5)\r\n   do\r\n      l=`expr $i \\* 497 + 191`\r\n      <strong>convert -crop 300x1285+$l+0 scanbin.png col_$i.png<\/strong>\r\n      tesseract col_$i.png col_$i nobatch digits\r\n      awk NF col_$i.txt &gt;&gt; list.txt\r\n   done\r\n<\/pre>\n<p>Mit Hilfe des convert befehls lassen sich per <code>--crop<\/code> die einzelnen Spalten ausschneiden. In meinem Fall sind sie 300 pixel breit, 1285 pixel hoch. Die erste Spalte mit iTANS beginnt mit 191 pixel Abstand vom linken Rand, alle folgenden jeweils noch 497 pixel weiter rechts.<\/p>\n<h2>2.5 Texterkennung auf Zahlen beschr\u00e4nken<\/h2>\n<p>L\u00e4sst man Tesseract ohne weitere Beschr\u00e4nkungen auf die zuvor ausgeschnittenen iTAN Spalten los, so wird das Ergebnis immer noch unbefriedigend sein. Dies liegt im wesentlichen daran, dass der OCR Software ein Hinweis fehlt, dass sie ausschlie\u00dflich nach Ziffern und nicht etwa nach Buchstaben suchen soll.<\/p>\n<p>Durch die Parameter <code>nobatch digits<\/code> kann man Tesseract mitteilen, dass die Textvorlage ausschlie\u00dflich aus Ziffern besteht. Dadurch werden jede Menge Zweideutigkeiten &#8211; etwa dass irrt\u00fcmlich eine 6 als b, eine 1 als I oder eine 5 als S erkannt werden &#8211; aufgel\u00f6st. Den Parameter zur Beschr\u00e4nkung von Tesseract auf Zahlen habe ich auf <a href=\"https:\/\/stackoverflow.com\/questions\/4944830\/how-to-make-tesseract-to-recognize-only-numbers-when-they-are-mixed-with-letter\" target=\"_blank\" rel=\"noopener noreferrer\">Stackoverflow<\/a> gefunden.<\/p>\n<h2>2.6 Falsch erkannte Leerzeilen entfernen<\/h2>\n<p>Der <code>awk<\/code>-Befehl in der <code>for<\/code>-Schleife, die durch die einzelnen Spalten der iTAN Liste geht, entfernt schlie\u00dflich fehlerhaft eingef\u00fcgte Leerzeilen aus dem ASCII-Text, so dass in der Reihenfolge der Orginalnumerierung der iTANs in jeder Zeile der ASCII-Ausgabe exakt die eine entsprechende iTAN-Nummer steht.<\/p>\n<h2>2.7 Zeilennumerierung hinzuf\u00fcgen<\/h2>\n<p>Nachdem die Datei list.txt 120 Zeilen mit jeweils einer iTAN in der urspr\u00fcnglichen Reihenfolge der Numerierung auf dem Papier-Original enth\u00e4lt, f\u00fcgen wir diese Nummern zur besseren Lesbarkeit wieder hinzu. Dies geschieht &#8211; nach Abschluss der for-Schleife mit einem weiteren <code>awk<\/code>-Kommando:<\/p>\n<pre class=\"lang:default decode:true\" title=\"Ausgabe der numeriererten iTANs\">awk '{print NR,$0}' list.txt<\/pre>\n<p>Die 120 iTANs werden Zeile f\u00fcr Zeile mit der entsprechenden Nummer davor auf der Konsole ausgegeben und k\u00f6nnen von dort als Klartext in den entsprechenden Passwort-Manager eingef\u00fcgt werden.<\/p>\n<h1>3. Zusammenfassung als Skript<\/h1>\n<p>S\u00e4mtliche Schritte des Abschnitts 2 k\u00f6nnen zu einem ausf\u00fchrbaren Skript zusammengefasst werden, das es erlaubt, eine komplette iTAN Liste direkt vom Scanner in eine Textausgabe umzuwandeln. Zur vereinfachung wird hier noch ein Arbeitsverzeichnis in der volatilen Ramdisk festgelegt, was den Vorteil hat, dass sp\u00e4testens nach einem Reboot keinerlei unverschl\u00fcsselte Datenreste auf dem Rechner verbleiben.<\/p>\n<pre class=\"lang:default decode:true \" title=\"Komplettes Skript zur OCR-Verarbeitung einer iTAN-Liste\">#!\/bin\/bash\r\n\r\nMYDIR=\/media\/ramdisk\r\n\r\nscanimage --device 'xerox_mfp:libusb:002:004' --format=pnm --mode 'Gray' --resolution 300 -l 6 -t 6 -y 74 -x 170  &gt; $MYDIR\/scan.pnm\r\n\r\nconvert -resize 150% $MYDIR\/scan.pnm $MYDIR\/scan.png\r\nrm $MYDIR\/scan.pnm\r\n\r\nconvert $MYDIR\/scan.png -threshold 30% $MYDIR\/scanbin.png\r\nrm $MYDIR\/scan.png\r\n\r\nfor i in $(seq 0 5)\r\n   do\r\n      l=`expr $i \\* 497 + 191`\r\n      convert -crop 300x1285+$l+0 $MYDIR\/scanbin.png col_$i.png\r\n      tesseract col_$i.png col_$i nobatch digits\r\n      awk NF col_$i.txt &gt;&gt; list.txt\r\n   done\r\n\r\nrm $MYDIR\/scanbin.png\r\n\r\nawk '{print NR,$0}' $MYDIR\/list.txt<\/pre>\n<h1>4. iTAN Listen der ING Diba<\/h1>\n<p>Die ING verschickt TAN Listen mit 196 Eintr\u00e4gen, die auf zwei Seiten mit jeweils 98 iTANs (001-098 und 099-198) gedruckt sind. Jede Seite enth\u00e4lt 6 Spalten. Da die Struktur der Seiten nicht 100% identisch ist, empfiehlt es sich jede Seite einzeln einzulesen. Au\u00dferdem m\u00fcssen die Parameter jeweils leicht angepasst werden.<\/p>\n<h2>4.1 Erste Seite (iTAN 001-098)<\/h2>\n<h3>Scannen und Vorbehandlung<\/h3>\n<pre class=\"lang:default decode:true\" title=\"Scanning the list\">scanimage --device 'xerox_mfp:libusb:002:003' --format=pnm --mode 'Gray' --resolution 300 -l 6 -t 19 -y 64 -x 170 &gt; scan.pnm\r\nconvert -resize 150% scan.pnm scan.png\r\nconvert scan.png -threshold 50% scanbin.png\r\n<\/pre>\n<h3>Zuschneiden und Texterkennung<\/h3>\n<pre class=\"lang:default decode:true\" title=\"Cutting, converting and numbering\">for i in $(seq 0 6)\r\n   do\r\n      l=`expr $i \\* 410 + 201`\r\n      convert -crop 250x1105+$l+0 scanbin.png col_$i.png\r\n      tesseract col_$i.png col_$i nobatch digits\r\n      awk NF col_$i.txt &gt;&gt; list.txt\r\n   done\r\n<\/pre>\n<h2>4.2 Zweite Seite (iTAN 099-198)<\/h2>\n<h3>Scannen und Vorbehandlung<\/h3>\n<pre class=\"lang:default decode:true\" title=\"Scanning the list\">scanimage --device 'xerox_mfp:libusb:002:003' --format=pnm --mode 'Gray' --resolution 300 -l 6 -t 13 -y 64 -x 170  &gt; scan.pnm\r\nconvert -resize 150% scan.pnm scan.png\r\nconvert scan.png -threshold 50% scanbin.png\r\n<\/pre>\n<h3>Zuschneiden und Texterkennung<\/h3>\n<pre class=\"lang:default decode:true\" title=\"Cutting, converting and numbering\">for i in $(seq 0 6)\r\n   do\r\n      l=`expr $i \\* 410 + 201`\r\n      convert -crop 250x1105+$l+0 scanbin.png col_$i.png\r\n      tesseract col_$i.png col_$i nobatch digits\r\n      awk NF col_$i.txt &gt;&gt; list.txt\r\n   done\r\n<\/pre>\n<p>ggg<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Obgleich die iTAN als Auslaufmodell gilt, schicken viele Finanzinstitute ihren Kunden weiterhin solche Listen als &#8220;fall back&#8221;, wenn moderne Verfahren scheitern. Meine Hausbank versendet solche Listen in einem Format, das<span class=\"more-button\"><a href=\"https:\/\/hobbykeller.spdns.de\/?p=1099\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\">iTAN Listen mit Hilfe von OCR einlesen<\/span><\/a><\/span><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[64],"tags":[249,248,247,243,246,244,245],"class_list":["post-1099","post","type-post","status-publish","format-standard","hentry","category-linux","tag-awk","tag-convert","tag-imagemagick","tag-itan","tag-linux","tag-ocr","tag-tesseract"],"_links":{"self":[{"href":"https:\/\/hobbykeller.spdns.de\/index.php?rest_route=\/wp\/v2\/posts\/1099","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hobbykeller.spdns.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hobbykeller.spdns.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hobbykeller.spdns.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/hobbykeller.spdns.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1099"}],"version-history":[{"count":9,"href":"https:\/\/hobbykeller.spdns.de\/index.php?rest_route=\/wp\/v2\/posts\/1099\/revisions"}],"predecessor-version":[{"id":1276,"href":"https:\/\/hobbykeller.spdns.de\/index.php?rest_route=\/wp\/v2\/posts\/1099\/revisions\/1276"}],"wp:attachment":[{"href":"https:\/\/hobbykeller.spdns.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1099"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hobbykeller.spdns.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1099"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hobbykeller.spdns.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1099"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}