likes
comments
collection
share

Python进行DES 加密和解密 解决和java结果不一致的问题

作者站长头像
站长
· 阅读数 2

Python DES CBC 加密解密代码示范

import binascii
from pyDes import des, CBC, PAD_PKCS5


def des_encrypt(s):
    """
    DES 加密
    :param s: 原始字符串
    :return: 加密后字符串,16进制
    """
    secret_key = '20171117'
    iv = secret_key
    k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    en = k.encrypt(s, padmode=PAD_PKCS5)
    return binascii.b2a_hex(en)


def des_descrypt(s):
    """
    DES 解密
    :param s: 加密后的字符串,16进制
    :return:  解密后的字符串
    """
    secret_key = '20171117'
    iv = secret_key
    k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    de = k.decrypt(binascii.a2b_hex(s), padmode=PAD_PKCS5)
    return de


str_en = des_encrypt('zx')
print(str_en)
str_de = des_descrypt(str_en)
print(str_de)

执行以上 Python 代码,得到以下输出:

1dbbd4e9246ebffa
zx

Java DES CBC 加密解密代码示范

import javax.crypto.spec.IvParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;


public class Main {

    public static void main(String[] args) {
        String content = "zx";
        String key = "20171117";

        System.out.println("加密前:" + content);
        byte[] encrypted = DES_CBC_Encrypt(content.getBytes(), key.getBytes());
        System.out.println("加密后:" + byteToHexString(encrypted));

        byte[] decrypted = DES_CBC_Decrypt(encrypted, key.getBytes());
        System.out.println("解密后:" + new String(decrypted));
    }

    public static byte[] DES_CBC_Encrypt(byte[] content, byte[] keyBytes) {
        try {
            DESKeySpec keySpec = new DESKeySpec(keyBytes);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey key = keyFactory.generateSecret(keySpec);

            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(keySpec.getKey()));
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            System.out.println("exception:" + e.toString());
        }
        return null;
    }

    private static byte[] DES_CBC_Decrypt(byte[] content, byte[] keyBytes) {
        try {
            DESKeySpec keySpec = new DESKeySpec(keyBytes);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey key = keyFactory.generateSecret(keySpec);

            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(keyBytes));
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            System.out.println("exception:" + e.toString());
        }
        return null;
    }

    private static String byteToHexString(byte[] bytes) {
        StringBuffer sb = new StringBuffer(bytes.length);
        String sTemp;
        for (int i = 0; i < bytes.length; i++) {
            sTemp = Integer.toHexString(0xFF & bytes[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }
}

执行以上 Java 代码,输出:

加密前:zx
加密后:1DBBD4E9246EBFFA
解密后:zx

注意事项

python中还有一个库Crypto 也是用于加密的, 但是加密的结果和java不一致, 这是个坑, 以下是Crypto加密的代码, 用于对比:

from Crypto.Cipher import DES
import binascii
import base64

# data->被加密的字符串 key->密钥 同样传入字符串
def des_decode(data, key):
    b_data = base64.b64decode(data)
    iv = key.encode()
    cipher = DES.new(key.encode(), iv,DES.MODE_CBC)
    decrypted = cipher.decrypt(b_data)
    decrypted.rstrip(b' ')
    return decrypted.decode()  # 解密完成后将加密时添加的多余字符'\0'删除




# data->被加密的字符串 key->密钥 同样传入字符串
def aes_encrypt(data, key):
    # DES CBC模式 需向量iv
    iv = key.encode()
    cipher = DES.new(key.encode(),iv, DES.MODE_CBC)
    # 字符串转字节数组
    b_data = data.encode()
    # ------ 按照16位对其 不足的补空格 ----
    block_size = DES.block_size
    count = len(b_data)
    # text不是16的倍数那就补足为16的倍数
    add_count = block_size - (count % block_size)
    s_plaintext = data + (' ' * add_count)
    # ------ 按照16位对其 不足的补空格 ----
  
    b_plaintext = s_plaintext.encode()
    encrypted = cipher.encrypt(b_plaintext)  # des加密

    return base64.b64encode(encrypted).decode()

转载自:https://juejin.cn/post/7021722196355743775
评论
请登录