des加密 java_java种的DES加密

项目中的加密算法

问题描述

在项目中使用了Des加密算法,我在本机增加用户加密了密码,实现了用户的登陆注册,然后将数据库备份给同事,同事再跑这个项目解密时就报错了。

分析原因

猜测:Des加密时和本机有联系,只有在本机加密的密码才能在本机解密。

更新:上面的猜测狗屁不通,DES是对称加密,只要秘匙相同就能正常加密解密。于是网上查了查,DES的入口参数有Data,model,填充模式。我使用的是"DES"它是采用默认的model和填充模式,在加密解密时会将其填充为8字节的整数倍。

尝试第一次解决

既然是这样,那我将加密解密都设置为"DES/ECB/NoPadding",结果报错说数据必须是8字节的整数倍。

尝试第二次解决

将输入的字符串格式化为8字节的整数倍,将输出的bytes[]数组截取出不为空的部分转为化String结果成功了。

简析加密算法原理

首先将64位的str进行顺序置换,然后分成32位的L0,R0两部分。然后L1=R(n-1),Rn=L(n-1)^f(keyN,L(n-1))这种算法计算16次得到L16和R16最后将他们合成64位输出。KeyN=C0+D0 C0=key的前28位循环左移一位或者两位,D0=key的后28位循环左移一位或者两位

DES Utils

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;

import javax.crypto.KeyGenerator;

import java.security.Key;

import java.security.NoSuchAlgorithmException;

import java.security.SecureRandom;

public class CryptionUtil {

public static Key DEFAULT_KEY = null;

//1qaz2wsx3edc$RFV%TGB^YHN&UJM

public static final String DEFAULT_SECRET_KEY = "1qaz2wsx3edc$RFV%TGB^YHN&UJM";

//不能写成DES,如果写成DES加密时会自动填充成64位,在解密时没有去除尾部就会发生问题。

public static final String DES_Content = "DES/ECB/NoPadding";

public static final String DES_Key= "DES";

static {

DEFAULT_KEY = obtainKey(DEFAULT_SECRET_KEY);

}

/**

* 获得key

**/

public static Key obtainKey(String key) {

if (key == null) {

return DEFAULT_KEY;

}

KeyGenerator generator = null;

try {

generator = KeyGenerator.getInstance(DES_Key);

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

}

generator.init(new SecureRandom(key.getBytes()));

Key key1 = generator.generateKey();

generator = null;

return key1;

}

/**

* 加密

* String明文输入,String密文输出

*/

public static String encode(String str) {

return encode(null, str);

}

/**

* 加密

* String明文输入,String密文输出

*/

public static String encode(String key, String str) {

//将str补齐8字节的整数倍

byte[] bytes=formatData(str);

return Base64.encodeBase64URLSafeString(obtainEncode(key,bytes));

}

/**

* 解密

* 以String密文输入,String明文输出

*/

public static String decode(String str) {

return decode(null, str);

}

/**

* 解密

* 以String密文输入,String明文输出

*/

public static String decode(String key, String str) {

//通过DES算法解密得到正确的bytes[]

byte[] bytes=obtainDecode(key, Base64.decodeBase64(str));

//将bytes[]末尾补齐的空白去掉返回。

return formatByte(bytes);

}

/**

* 加密

* 以byte[]明文输入,byte[]密文输出

*/

private static byte[] obtainEncode(String key, byte[] str) {

byte[] byteFina = null;

Cipher cipher;

try {

Key key1 = obtainKey(key);

cipher = Cipher.getInstance(DES_Content);

cipher.init(Cipher.ENCRYPT_MODE, key1);

byteFina = cipher.doFinal(str);

} catch (Exception e) {

e.printStackTrace();

} finally {

cipher = null;

}

return byteFina;

}

@Override

public int hashCode() {

return super.hashCode();

}

/**

* 解密

* 以byte[]密文输入,以byte[]明文输出

*/

private static byte[] obtainDecode(String key, byte[] str) {

Cipher cipher;

byte[] byteFina = null;

try {

Key key1 = obtainKey(key);

cipher = Cipher.getInstance(DES_Content);

cipher.init(Cipher.DECRYPT_MODE, key1);

byteFina = cipher.doFinal(str);

} catch (Exception e) {

e.printStackTrace();

} finally {

cipher = null;

}

return byteFina;

}

//将str转为8的整数倍的byte[]

public static byte[] formatData(String str){

try{

byte[] data=str.getBytes("UTF-8");

int size=8-(data.length%8);

byte[] result=new byte[data.length+size];

for(int i=0;i

result[i]=data[i];

}

return result;

}catch (Exception e){

System.out.println(e.getMessage());

}

return null;

}

//将byte[]去掉空行转为Str

public static String formatByte(byte[] bytes){

int i=0;

for(;i

if(bytes[i]==0){

break;

}

}

byte[] result=new byte[i];

for(int j=0;j

result[j]=bytes[j];

}

try{

return new String(result,"UTF-8");

}catch (Exception e){

System.out.println(e.getMessage());

}

return null;

}

public static void main(String[] args) {

//String 中一个英文字符占一个字节,中文根据编码不同所占字节数不同。UFT-8占3个字节,GBK占两个字节。

String a = "admin1";

//encode的str必须是8字节的整数倍,key没做要求

String m = encode(a);

System.out.println(m);

String n = decode(m);

System.out.println(n);

// String str="abcdefg";

// byte[] bytes=formatData(str);

// String result=formatByte(bytes);

// System.out.println(result);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值