为什么在尝试解码我​​的base32字符串时出现“不正确的填充”错误?

时间:2018-08-24 21:58:54

标签: python-3.x

在尝试使用Incorrect padding函数在python中解码BASE32字符串时,出现base64.b32decode()错误。我认为我的填充正确。我在哪里弄错了?

import base64

my_string=b'SOMESTRING2345'
print(my_string)
print("length     : "+str(len(my_string)))
print("length % 8 : "+str(len(my_string)%8))

p_my_string = my_string+b'='*(8-(len(my_string)%8))

print("\nPadded:\n"+str(p_my_string))
print("length     : "+str(len(p_my_string)))

b32d = base64.b32decode(p_my_string)
print("\nB32 decode : " + str(b32d))
print("length     : " + str(len(b32d)))

运行此代码会让我

b'SOMESTRING2345'
length     : 14
length % 8 : 6

Padded:
b'SOMESTRING2345=='
length     : 16

---------------------------------------------------------------------------
Error                                     Traceback (most recent call last)
<ipython-input-2-9fe7cf88581a> in <module>()
     10 print("length     : "+str(len(p_my_string)))
     11 
---> 12 b32d = base64.b32decode(p_my_string)
     13 print("\nB32 decode : " + str(b32d))
     14 print("length     : " + str(len(b32d)))

/opt/anaconda3/lib/python3.6/base64.py in b32decode(s, casefold, map01)
    244             decoded[-5:] = last[:-4]
    245         else:
--> 246             raise binascii.Error('Incorrect padding')
    247     return bytes(decoded)
    248 

Error: Incorrect padding
 ​

但是,如果将my_string更改为b'SOMESTRING23456',我的代码将与输出完美配合-

b'SOMESTRING23456'
length     : 15
length % 8 : 7

Padded:
b'SOMESTRING23456='
length     : 16

B32 decode : b'\x93\x98IN(i\xb5\xbew'
length     : 9

1 个答案:

答案 0 :(得分:2)

没有合法的14个字符的base32字符串。模数8之外的任何余数只能为2、4、5或7个字符,因此填充必须始终为6、4、3或1个=字符,其他任何长度均无效。由于剩余的6个字符不是合法的base32编码,因此base32decode()函数除了拒绝使用无效的5填充字符(而不是有效的=填充字符)之外,无法执行任何操作。

base32字符编码5位,并且字节始终为8位长。这意味着您不需要为5个字节的倍数输入填充(5乘8 == 40位,可以干净地编码8个字符)。

因此对5的倍数上的任何余数进行编码

  • 1字节= 8位:2个字符(10位)
  • 2字节= 16位:4个字符(20位)
  • 3个字节= 24位:5个字符(25位)
  • 4字节= 32位:7个字符(35位)

14个字符将保留70位,这是8字节(64位),其中有6位备用,因此字符14将没有任何意义!

因此,对于任何剩余的1、3或6个字符的base32字符串,无论您添加多少个Incorrect padding字符,您都将始终遇到=异常。

请注意,余数的最后一个字符编码的位数有限,因此也将落入特定范围内;对于2个字符(编码1个字节),第二个字符仅对3位进行编码,最后2位保留为0,因此只能使用A,E,I,M,Q,U,Y和4(因此,第4个字符base32字母,AZ + 2-7)。由于有4个字符,最后一个字符仅代表一位,因此只有A和Q是合法的。 5个字符留下1个冗余位,因此可以使用第二个字符(A,C,E等),而对于7个字符和3个冗余位,则可以使用第8个字符(A,I,Q,Y)。

解码器可以选择在最后一个位置接受所有可能的base32字符,而只是掩盖仍然需要的位,因此对于2个字符,B7或其他任何一个无效字符仍然可以导致成功解码,但是AAABACAD之间没有区别,所有4个仅使用前3位第二个字符中的第一个字符和所有4个序列解码为十六进制值0x00