A-A+

Python 使用DES加密(PKCS5Padding)

2021年04月10日 23:28 汪洋大海 暂无评论 阅读 57 views 次

今天在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/ 此博客已经打不开了。

布施恩德可便相知重

微信扫一扫打赏

支付宝扫一扫打赏

×

给我留言