python和java中Des加密初试

来源:互联网 发布:制作毕业证软件 编辑:程序博客网 时间:2024/05/16 11:50
    项目中需要做一个Des加密,牵扯好几家单位,但人家都用java来实现,只用调用相同的代码就好,而我们后台用的python。我初步想到有两种办法来解决这个问题:1、用python来实现des加密功能,保证相同的字符串通过java和python加密出来的密文相同;2、如果第一条行不通,就需要直接利用他们的加密算法,然后想办法用python来调用,以实现加密。
     首先对Des算法做简单了解,见百度百科:数据加密算法。此处对具体实现过程不做讨论。
     接下来看java实现Des加密的算法:
package com.core.util;

import java.security.Key;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class DesUtil {
private final static String encoding = "utf-8";

private static String getIVToday(){
return new SimpleDateFormat("yyyyMMdd").format(new Date());
}

private static String getIVYesterday(){
return new SimpleDateFormat("yyyyMMdd").format(new Date(new Date().getTime()-86400000));
}

private static String getIVTomorrow(){
return new SimpleDateFormat("yyyyMMdd").format(new Date(new Date().getTime()+86400000));
}

private static String getSecretKeyToday(){
return "qaz_"+getIVToday()+"_wsx";
}

private static String getSecretKeyYesterday(){
return "qaz_"+getIVYesterday()+"_wsx";
}

private static String getSecretKeyTomorrow(){
return "qaz_"+getIVTomorrow()+"_wsx";
}

/**
* 加密
* @param plainText
* @return
*/
public static String encode(String plainText) {
Key deskey = null;
byte[] encryptData = null;
String secretKey = getSecretKeyToday();
try {
DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
deskey = keyfactory.generateSecret(spec);

Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
IvParameterSpec ips = new IvParameterSpec(getIVToday().getBytes());
cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
encryptData = cipher.doFinal(plainText.getBytes(encoding));

BASE64Encoder base64Encoder = new BASE64Encoder();
return base64Encoder.encode(encryptData);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}

/**
* 解密
* @param data
* @return
*/
public static String decode(String data){
try {
Key deskey = null;
String secretKey = getSecretKeyToday();
DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
deskey = keyfactory.generateSecret(spec);
Cipher deCipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
IvParameterSpec ips = new IvParameterSpec(getIVToday().getBytes());
deCipher.init(Cipher.DECRYPT_MODE, deskey, ips);

BASE64Decoder base64Decoder = new BASE64Decoder();
byte[] pasByte = null;
try{
pasByte=deCipher.doFinal(base64Decoder.decodeBuffer(data));
}catch(BadPaddingException e){
secretKey = getSecretKeyYesterday();
spec = new DESedeKeySpec(secretKey.getBytes());
deskey = keyfactory.generateSecret(spec);
ips = new IvParameterSpec(getIVYesterday().getBytes());
deCipher.init(Cipher.DECRYPT_MODE, deskey, ips);
try{
pasByte=deCipher.doFinal(base64Decoder.decodeBuffer(data));
}catch(BadPaddingException e1){
secretKey = getSecretKeyTomorrow();
spec = new DESedeKeySpec(secretKey.getBytes());
deskey = keyfactory.generateSecret(spec);
ips = new IvParameterSpec(getIVTomorrow().getBytes());
deCipher.init(Cipher.DECRYPT_MODE, deskey, ips);

pasByte=deCipher.doFinal(base64Decoder.decodeBuffer(data));
}
}
return new String(pasByte,"UTF-8");
} catch (Exception e) {}
return "";
}

public static void main(String[] args) {
System.out.println(DesUtil.encode("phonenum=12345678901"));
}
}

以上代码中,最为关键的就是了解Cipher类,3.3.5 Cipher类。

python实现Des加密的基本思路:1、自己重写Des加密算法 python实现DES加密    2、调用pyDes:
from pyDes import *

# For Python3, you'll need to use bytes, i.e.:
# data = b"Please encrypt my data"
# k = des(b"DESCRYPT", CBC, b"\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5)

data = "userPhone=12345678901"
k = triple_des("123456781234567812345678", CBC, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5)
d = k.encrypt(data)
print "Encrypted: %r" % d
print "Decrypted: %r" % k.decrypt(d)
assert k.decrypt(d, padmode=PAD_PKCS5) == data
其中triple_des中要求秘钥为16位或24位,des方法需要8位。

但两种形式中,可传递的参数只有需加密字符串和秘钥(长度为8的倍数),并没有java中那个随机向量的概念。由于没有时间研究Cipher的源码,所以用python来实现以上java算法算是泡汤了。下一篇文章说明如何使用JPype实现python调用java代码。

0 0
原创粉丝点击