Java和Python中的des加密实现

编程/技术 2019-08-19 @ 14:21:46 浏览数: 100 净访问: 75 By: skyrover

本博客采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载本博客文章必须也遵循署名-非商业用途-保持一致的创作共用协议


首先是3DES的一些介绍,引用自多语言3DES加解密举例

DES使用分块加密,加密密钥为56位,块大小为64位。由于56位版本的DES加密非常容易破解(一般机器一天以内),就有了和DES兼容性较好的3DES算法。

原理

3DES加密算法表示为C=EncryptK3(DecryptK2(EncryptK1(message))),如果K1、K2、K3为密钥,如果各不相同,则相当于加密密钥长度为112(由于中途相遇攻击);

解密算法表示为message=DecryptK1((EncryptK2(DecryptK3(C)))

以加密算法举例:

  • 使用了3次DES算法,有3个密钥
  • 加密时第一个密钥K1用来加密消息(P),输出C1密文
  • 第二个密钥K2用来解密C1,输出C2密文
  • 第三个密钥K3用来加密C2,输出C3密文

分组密码工作模式

分组密码的工作模式允许使用同一个分组密码密钥对多于一块的数据进行加密,并保证其安全性。分组密码自身只能加密长度等于密码分组长度的单块数据,若要加密变长数据,则数据必须先被划分为一些单独的密码块。通常而言,最后一块数据也需要使用合适填充方式将数据扩展到匹配密码块大小的长度。一种工作模式描述了加密每一数据块的过程,并常常使用基于一个通常称为初始化向量的附加输入值以进行随机化,以保证安全。

对于分组密码工作模式的介绍可参考wiki

常见的工作模式包括ECB,CBC,OFB和CFB等。

分组密码初始化向量(IV)

用于将加密随机化的一个位块,由此即使同样的明文被多次加密也会产生不同的密文,避免了较慢的重新产生密钥的过程。

分组密码填充

块密码只能对确定长度的数据块进行处理,而消息的长度通常是可变的。因此部分模式(即ECB和CBC)需要最后一块在加密前进行填充。

加密后字节转文本

对消息加密后通常会得到字节数组,在传输时一般会使用BASE64或HEX等进行编码。

Java中的加密代码

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
private static String CryptAlgorithm = "DESede/CBC/PKCS5Padding";
private static String KeyAlgorithm = "DESede";
public static byte[] defaultIV = {1, 2, 3, 4, 5, 6, 7, 8};

/* KeyStr 是加密字符串 */
input = Hex.decode(KeyStr);
DESedeKeySpec KeySpec = new DESedeKeySpec(input);
SecretKeyFactory KeyFactory = SecretKeyFactory.getInstance(KeyAlgorithm);
k = KeyFactory.generateSecret(KeySpec);
try {
    IvParameterSpec IVSpec = (byteIV.length == 0) ? IvGenerator(defaultIV) : IvGenerator(byteIV);
    Cipher c = Cipher.getInstance(CryptAlgorithm);
    c.init(1, k, IVSpec);
    output = c.doFinal(input);


} catch (Exception ex) {
    return "inner Encrypt error:" + ex.getMessage();
}

在Java中的IV,表示为字节数组,数组每一项是一个字节,8位,可以组成2^8=256中不同数字。byte存值范围: -128 - 127,对应Python中就是\x,表示的是十六进制的意思,后面跟两位,表示单字节编码。所以Java中:public static byte[] defaultIV = {1, 2, 3, 4, 5, 6, 7, 8}; 对应Python中就是:defaultIV = b'\x01\x02\x03\x04\x05\x06\x07\x08'

Python中的加密代码

import pyDes
def encrypt(string, encrypt_key, iv):
    input_bytes = string.encode('utf-8')
    _bytes = bytes.fromhex(encrypt_key)
    des = pyDes.triple_des(_bytes, mode=pyDes.CBC, IV=iv, pad=None, padmode=pyDes.PAD_PKCS5)
    encrypted = des.encrypt(input_bytes, padmode=pyDes.PAD_PKCS5)
    return base64.b64encode(encrypted).decode('utf-8')

解密的,就调用decrypt方法就可以了

def decrypt(string, decrypt_key, iv):
    input_bytes = base64.b64decode(string)
    des = pyDes.triple_des(bytes.fromhex(decrypt_key), mode=pyDes.CBC, IV=iv, pad=None, padmode=pyDes.PAD_PKCS5)
    decrypted = des.decrypt(input_bytes, padmode=pyDes.PAD_PKCS5)
    return decrypted


点赞走一波😏


评论

提交评论