File tree Expand file tree Collapse file tree 4 files changed +74
-1
lines changed Expand file tree Collapse file tree 4 files changed +74
-1
lines changed Original file line number Diff line number Diff line change @@ -91,6 +91,21 @@ a file:
91
91
writer.write(result.challenge_matrix[1 ])
92
92
writer.close()
93
93
94
+ Some banks, like Comdirect, may provide the challenge within the ``challenge_hhduc `` attribute. We provide a helper function to decode the challenge. Pass the ``challenge_hhduc `` value to this method:
95
+
96
+ .. autofunction :: fints.hhd.utils.decode_phototan_image
97
+
98
+ This returns a dictionary with a ``mime_type `` and an ``image `` field. The ``image `` field contains the binary data
99
+ of the image itself and can e.g. be written to a file
100
+
101
+ .. code-block :: python
102
+ from fints.utils import decode_phototan_image
103
+
104
+ data = decode_phototan_image(challenge_hhduc)
105
+ writer = open (" tan.png" , " wb" )
106
+ writer.write(data[" image" ])
107
+ writer.close()
108
+
94
109
Sending the TAN
95
110
---------------
96
111
Original file line number Diff line number Diff line change @@ -10,7 +10,7 @@ Bank Transactions Holdings Transfer Debits
10
10
Postbank Yes
11
11
BBBank eG Yes Yes
12
12
Sparkasse Heidelberg Yes
13
- comdirect Yes
13
+ comdirect Yes Yes
14
14
======================================== ============ ======== ======== ======
15
15
16
16
Tested security functions
Original file line number Diff line number Diff line change @@ -351,3 +351,34 @@ def changed(reduced=False):
351
351
except ImportError :
352
352
def doc_enum (an_enum : EnumType ) -> EnumType :
353
353
return an_enum
354
+
355
+
356
+ def decode_phototan_image (data ):
357
+ """
358
+ This decodes photoTAN data sent as challenge_hhduc into its mime type and the actual image data.
359
+
360
+ :returns: a dictionary with two values, 'mime_type' and 'image'
361
+ :rtype: dict
362
+
363
+ The markup of the data is taken from https://github.com/hbci4j/hbci4java/blob/c8eabe6809e8d0271f944ea28a59ed6b736af56e/src/main/java/org/kapott/hbci/manager/MatrixCode.java#L61-L97
364
+ The encoding is taken from https://github.com/hbci4j/hbci4java/blob/c8eabe6809e8d0271f944ea28a59ed6b736af56e/src/main/java/org/kapott/hbci/comm/Comm.java#L46
365
+ """
366
+ # Mime type length is the first two bytes of data
367
+ mime_type_length = int .from_bytes (data [:2 ], byteorder = 'big' )
368
+
369
+ # The mime type follows from byte three to (mime_type_length - 1)
370
+ mime_type = data [2 :2 + mime_type_length ].decode ("iso-8859-1" )
371
+
372
+ # The image length is coded in the next two bytes
373
+ image_length_start = 2 + mime_type_length
374
+ image_length = int .from_bytes (data [image_length_start :2 + image_length_start ], byteorder = 'big' )
375
+
376
+ # The actual image data is everything that follows.
377
+ # To be compatible with possible future extensions, we still slice the data
378
+ image = data [2 + image_length_start : 2 + image_length_start + image_length ]
379
+
380
+ return {
381
+ "mime_type" : mime_type ,
382
+ "image" : image
383
+ }
384
+
Original file line number Diff line number Diff line change
1
+ import pytest
2
+ from fints .utils import decode_phototan_image
3
+
4
+
5
+ # HITAN3:
6
+ # 'challenge' contains a HHD 1.3 code embedded in the normal text payload
7
+ # field.
8
+ # Example: 'CHLGUC 00312908881344731012345678900515,00CHLGTEXT0292Sie haben eine ...'
9
+ # The code in NeedTANResponse._parse_tan_challenge extracts
10
+ # '2908881344731012345678900515,00'
11
+ # from this, as a version 1.3 code. parse() should accept it
12
+ # (start code: '88134473', IBAN: '1234567890', amount: '15,00')
13
+
14
+ # HITAN6:
15
+ # 'challenge' contains 4 fields:
16
+ # 2 bytes: mime type length
17
+ # x bytes (see above): mime type
18
+ # 2 bytes: data length
19
+ # y bytes: image data
20
+
21
+ CHALLENGE = b'\x00 \t image/png\x0e \x82 \x89 PNG\r \n \x1a \n \x00 \x00 \x00 \r IHDR\x00 \x00 \x00 \xc8 \x00 \x00 \x00 \xc8 \x08 \x06 \x00 \x00 \x00 \xad X\xae \x9e \x00 \x00 \x00 \x06 bKGD\x00 \xff \x00 \xff \x00 \xff \xa0 \xbd \xa7 \x93 \x00 \x00 \x02 MIDATx\x9c \xed \xdd \xb1 \r \xc4 0\x0c \x04 A\xea \xe1 \xfe [\xf6 w\xb0 \x89 \x02 3\x98 \xa9 @ \xb0 Pxgf\xde Y\xec }W?o\xce 9_?!\xb9 \xdf \x9d \xdf \xd7 \x0f \x80 \xcd \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x1e ;\xda w\xdc \xef \xce \xf6 \xfb \xf9 A \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x9c \x99 Y=T\xbd }G\xdb \x0e \xf9 \x9d \xed \xf7 \xf3 \x83 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @x\xec h\xdf q\xbf ;\xdb \xef \xe7 \x07 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 pff\xf5 P\xf5 \xf6 \x1d m;\xe4 w\xb6 \xdf \xcf \x0f \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 \xe1 \x0f p-(\x89 A#\xd8 \xc6 \x00 \x00 \x00 \x00 IEND\xae B`\x82 '
22
+
23
+ def test_decode_phototan_image ():
24
+ data = decode_phototan_image (CHALLENGE )
25
+
26
+ assert data ["mime_type" ] == "image/png"
27
+ assert data ["image" ] == b'\x89 PNG\r \n \x1a \n \x00 \x00 \x00 \r IHDR\x00 \x00 \x00 \xc8 \x00 \x00 \x00 \xc8 \x08 \x06 \x00 \x00 \x00 \xad X\xae \x9e \x00 \x00 \x00 \x06 bKGD\x00 \xff \x00 \xff \x00 \xff \xa0 \xbd \xa7 \x93 \x00 \x00 \x02 MIDATx\x9c \xed \xdd \xb1 \r \xc4 0\x0c \x04 A\xea \xe1 \xfe [\xf6 w\xb0 \x89 \x02 3\x98 \xa9 @ \xb0 Pxgf\xde Y\xec }W?o\xce 9_?!\xb9 \xdf \x9d \xdf \xd7 \x0f \x80 \xcd \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x1e ;\xda w\xdc \xef \xce \xf6 \xfb \xf9 A \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x08 \x04 \x82 @ \x9c \x99 Y=T\xbd }G\xdb \x0e \xf9 \x9d \xed \xf7 \xf3 \x83 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @\x10 \x08 \x04 \x81 @x\xec h\xdf q\xbf ;\xdb \xef \xe7 \x07 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 \x10 \x08 \x02 \x81 pff\xf5 P\xf5 \xf6 \x1d m;\xe4 w\xb6 \xdf \xcf \x0f \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 A \x10 \x04 \x02 \xe1 \x0f p-(\x89 A#\xd8 \xc6 \x00 \x00 \x00 \x00 IEND\xae B`\x82 '
You can’t perform that action at this time.
0 commit comments