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:
9191 writer.write(result.challenge_matrix[1 ])
9292 writer.close()
9393
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+
94109 Sending the TAN
95110---------------
96111
Original file line number Diff line number Diff line change @@ -10,7 +10,7 @@ Bank Transactions Holdings Transfer Debits
1010Postbank Yes
1111BBBank eG Yes Yes
1212Sparkasse Heidelberg Yes
13- comdirect Yes
13+ comdirect Yes Yes
1414======================================== ============ ======== ======== ======
1515
1616Tested security functions
Original file line number Diff line number Diff line change @@ -351,3 +351,34 @@ def changed(reduced=False):
351351except ImportError :
352352 def doc_enum (an_enum : EnumType ) -> EnumType :
353353 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