A-A+
Python 使用DES加密(PKCS5Padding)
今天在Python里面简单的做了一下DES算法需要的padding方法,Java方面使用的Padding方式是PKCS5,按照标准,PKCS5Pading的方式是在加密的字符串后面补齐,使得加密字符串的长度为8的整数倍。
比如ABCDEF长度为6,需要补两个字符,如果采用0Padding的方式则缺多少就补多少'x00',在需要的是PKCS5Padding,简单的说就是需要补几个就补几个几8-6=2 需要补2个,就补2个2括号中的内容('x02'),于是加密前的字符串为‘A’、‘B’、‘C’、‘D’、‘E’、‘F’、‘x02’、‘x02’。
特殊的是如果刚好是长度是8的整数倍的时候仍然需要再补8个8(‘x08’),如ABCDEFGH,需要补成 ‘A’、‘B’、‘C’、‘D’、‘E’、‘F’、‘G’、‘H’、‘x08’、‘x08’、‘x08’、‘x08’、‘x08’、‘x08’、‘x08’、‘x08’,之前没想清楚为什么,直到做解密部分的时候才想清楚。
因为如果不这么做,万一加密前的字符串刚好就是以’x01’结尾,或者’x02’、‘x02’ 这样的字符结尾,并且长度刚好是8的整数倍的时候,解密的时候就出现二义性了。
如果加密前的字符串刚好以’x01’,那么解密的时候就会当成这是一个padding,而将其去掉,规定了如果长度是8的整数倍的时候需要再补8个’x08’,则可以避免这样的问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | from binascii import b2a_hex, a2b_hex from Crypto.Cipher import DES DES_CRYPTO_UNIT_LENGTH = 8 DES_CRYPTO_KEY = "12345678" #这个Key如果超过8个字符,多余的部分会被丢弃,不会影响结果 def encrypt_by_des(id_to_be_encrypted): ''' DES 加密 使用KPCS5进行padding ''' # 设置加密密钥,初始化加密器 e = DES.DESCipher(config.DES_CRYPTO_KEY) # 原字符串长度 length = len(id_to_be_encrypted) # 计算padding长度 padding_length = DES_CRYPTO_UNIT_LENGTH - length % DES_CRYPTO_UNIT_LENGTH # 根据padding长度 设置padding padding = chr(padding_length) # 补齐字符串 id_with_padding = id_to_be_encrypted + (padding * padding_length) # 对padding后的字符串进行加密 encrypted_byte_array = e.encrypt(id_with_padding) # 将加密后的byte数组转换成16进制字符串,【这个地方也可以进行base64编码】 encrypted_hex_string = b2a_hex(encrypted_byte_array) return encrypted_hex_string def decrypt_by_des(id_to_be_decrypted): ''' DES 解密 使用KPCS5进行padding ''' # 设置加密密钥,初始化加密器 e = DES.DESCipher(config.DES_CRYPTO_KEY) # 将十六进制密文转换成byte数组 encrypted_byte_array = a2b_hex(id_to_be_decrypted) # 解密 获得带有padding的明文字符串 decrypted_id_with_padding = e.decrypt(encrypted_byte_array) # 获取最后一位,也就是padding的每一个单元的字符 padding = decrypted_id_with_padding[len(decrypted_id_with_padding)-1] # 根据padding计算padding长度 padding_length = ord(padding) # 校验padding的合法性 if padding_length > 8: LOGGER.error("PADDING LENGTH should not exceed 8") return None if decrypted_id_with_padding.endswith(padding*padding_length): LOGGER.error("PADDING MODE INVALID") return None # 移除padding得到明文 decrypted_id = decrypted_id_with_padding[:len(decrypted_id_with_padding) - padding_length] return decrypted_id |
文章来源:https://www.dazhuanlan.com/2019/12/10/5dee79bf8dd89/ 此博客已经打不开了。
布施恩德可便相知重
微信扫一扫打赏
支付宝扫一扫打赏