java加密解密算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
加密算法分类:
只能加密:SHA MD5
既能加密也能解密:
对称:DES RC4
非对称:RSA
非对称加密技术开销比较大,不适合大文本的加密。
SHA加密算法
SHA加密算法用途
数字签名、数字时间戳、数字证书
SHA加密原理以及流程
在SHA1算法中,我们必须把原始消息(字符串,文件等)转换成位字符串位。
SHA1算法只接受位作为输入。
假设我们对字符串”abc”产生消息摘要(也就是加密)。
首先,我们将它转换成位字符串如下:
01100001 01100010 01100011
‘a’=97 ‘b’=98 ‘c’=99
这个位字符串的长度为24。
下面我们需要5个步骤来计算SHA。
①补位
消息必须进行补位,以使其长度在对512取模以后的余数是448,也就是说,(补位后的消息长度)len%512=448。
即使长度已经满足对512取模后余数是448,补位也必须要进行。
补位是这样进行的:先补一个1,然后再补0,直到长度满足对512取模后余数是448.总而言之,补位是至少补一位,最多补512位。
还是以前面的“abc”
为例显示补位过程。
原始信息为:01100001 01100010 01100011
补位第一步:01100001 01100010 01100011 1(首先补一个1)
补位第二步:01100001 01100010 01100011 10....0(补423个0)
②补长度
所谓的补长度是将原始数据的长度补到已经进行了补位操作的消息后面。
通常一个64位的数据来表示原始消息的长度。
在进行了补长度的操作以后,整个消息就变成下面这样了。
如果原始的消息长度超过了512,我们需要将它补成512的倍数。
然后我们把整个消息分成一个一个512位的数据块,分别处理每一个数据块,从而得到消息摘要。
③
④
⑤
Java代码实现SHA算法
/*
SHA(Secure Hash Algorithm,安全散列算法),数字签名等密码学应用中重要的工具,
被广泛地应用于电子商务等信息安全领域。
虽然,SHA与MD5通过碰撞法都被破解了,但是SHA仍然是公认的安全加密算法,较之MD5更为安全*/
public class SHAEncode {
public static final String KEY_SHA = "SHA1";
public static String shaDigest(byte[] source) throws NoSuchAlgorithmException {
String encrpt = null;
MessageDigest md = MessageDigest.getInstance(KEY_SHA);
md.update(source);
//得到数据摘要
byte[] digest = md.digest();
//把二进制数组转换成十六进制字符串
encrpt = Byte2HexStrUtil.byte2HexStr(digest);
return encrpt;
}
}
MD5加密算法
MD5算法java实现
/**
* 获取加密后的字符串
* @param input
* @return
*/
public static String md5Digest(String data) {
try {
// 拿到一个MD5转换器(如果想要SHA1参数换成”SHA1”) MessageDigest messageDigest
=MessageDigest.getInstance("MD5");
// 输入的字符串转换成字节数组
byte[] inputByteArray = data.getBytes();
// inputByteArray是输入字符串转换得到的字节数组
messageDigest.update(inputByteArray);
// 转换并返回结果,也是字节数组,包含16个元素
byte[] resultByteArray = messageDigest.digest();
// 字符数组转换成字符串返回
return byteArrayToHex(resultByteArray);
} catch (NoSuchAlgorithmException e) {
return null;
}
}
public static String byteArrayToHex(byte[] byteArray) { // 首先初始化一个字符数组,用来存放每个16进制字符
char[] hexDigits= {'0','1','2','3','4','5','6','7','8','9', 'A','B','C','D','E','F' };
// new一个字符数组,这个就是用来组成结果字符串的(解释一下:一
个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方))
char[] resultCharArray =new char[byteArray.length * 2];
// 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符
数组中去
int index = 0;
for (byte b : byteArray) {
resultCharArray[index++] = hexDigits[b>>> 4 & 0xf];
resultCharArray[index++] = hexDigits[b& 0xf];
}
// 字符数组组合成字符串返回
return new String(resultCharArray);
}
DES加密算法
1)要被加密的数据被分割称为若干以64bit为单位的数据,如果位数不够,那么补00
或者FF,然后按照表1进行置换操作。
表1相当于一个函数。
2)把64位密钥按表2做置换,去除密钥中作为奇偶校验位的第8、16、24、32、40、
48、56、64位,剩下的56位作为有效输入密钥。
3)将56位有效密钥按表3左移位,总计进行16轮操作,每一轮移位结束之后,得
到的新的56位子密钥作为下一轮移位的有效密钥。
总计得到16个56位的子密钥。
4)按照表4对16个子密钥进行置换压缩,压缩后每个子密钥中的第9,18,22,25,35,38,43,54共8位数据会丢失。
此步骤完成后得到16个48位的子密钥。
5)将第一步生成的16个有效数据的右半部分R[1]的32位的数据根据表5进行置换,由原32位扩展到48位。
6)将扩展后的有效数据的新的R[1]和K[1]做异或运算得到16个48位的加密数据。
7)将第六步产生的48位的加密数据分为8个6位的数据,按照表6取值,每6位压缩成4位,最终形成8个4位的数据,组合成新的32位的数据。
8)将上步产生的32位的数据按照表7置换,生成新的32位的RR[1]数据。
9)把RR[1]和第一步产生的L【1】按位异或后的值赋给第一步产生的R【2】,然后原来的R 【1】值赋给L【2】,得到新的L【2】和R【2】
10)回到第5步,重复运算第9步,每轮计算由R【i】,L【i】,k【i】来计算。
总计16轮结束,最终生成新的L【16】和R【16】
11)合并L【16】和R【16】为64位的数据,然后按照表8做置换,生成最终加密数据
DES加密算法java实现
/**
* DES加密
* @param source
* @return
*/
public static String desEncrypt(String source){
if(source == null || source.length() ==0){
return null;
}
try {
//DES算法要求有一个可信任的随机数源
SecureRandom sr = new SecureRandom();
//从原始密钥数据创建一个DESKeySpec对象
DESKeySpec dks = new DESKeySpec(DES_KEY.getBytes());
SecretKeyFactory keyFactory =
SecretKeyFactory.getInstance("DES");
//生产密钥
SecretKey key = keyFactory.generateSecret(dks);
//Cipher对象实际完成加密操作
//使用密钥初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE,key,sr);
byte [] data =source.getBytes();
//加密
byte [] encryptedData = cipher.doFinal(data);
//转成16进制串
String hexString = HexUtil.byte2HexStr(encryptedData);
return hexString;
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
/**
* DES解密
* @param source
* @return
*/
public static String desDecrypt(String source){
if(source == null || source.length() ==0){
return null;
}
try {
//DES算法要求有一个可信任的随机数源
SecureRandom sr = new SecureRandom();
//从原始密钥数据创建一个DESKeySpec对象
DESKeySpec dks = new DESKeySpec(DES_KEY.getBytes());
SecretKeyFactory keyFactory =
SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(dks);
//Cipher对象实际完成解密操作
//使用密钥初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE,key,sr);
//将十六进制串转成字节数组
byte [] data =HexUtil.hex2Byte(source);
//解密
byte [] decryptedData = cipher.doFinal(data);
return new String(decryptedData);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
3DES加密算法
Java实现3DES加密算法
1、加入bcprov-jdk16-145.jar包支持
public class ThreeDESUtil {
// 算法名称
public static final String KEY_ALGORITHM = "desede";
// 算法名称/加密模式/填充方式
public static final String CIPHER_ALGORITHM= "desede/CBC/NoPadding";
/** *//**
* CBC加密
* @param key 密钥
* @param keyiv IV
* @param data 明文
* @return Base64编码的密文
* @throws Exception
*/
public static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data) throws Exception {
Security.addProvider(new BouncyCastleProvider());
Key deskey = keyGenerator(new String(key));
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
IvParameterSpec ips = new IvParameterSpec(keyiv);
cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
byte[] bOut = cipher.doFinal(data);
for (int k = 0; k < bOut.length; k++) {
System.out.print(bOut[k] + " ");
}
System.out.println("");
return bOut;
}
/** *//**
*
* 生成密钥key对象
* @param KeyStr 密钥字符串
* @return密钥对象
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws Exception
*/
private static Key keyGenerator(String keyStr) throws Exception { byte input[] = HexString2Bytes(keyStr);
DESedeKeySpec KeySpec = new DESedeKeySpec(input);
SecretKeyFactory KeyFactory= SecretKeyFactory.getInstance(KEY_ALGORITHM);
return((Key) (KeyFactory.generateSecret(((java.security.spec.KeySpec) (KeySpec)))));
}
private static int parse(char c) {
if (c >= 'a') return (c - 'a' + 10) & 0x0f;
if (c >= 'A') return (c - 'A' + 10) & 0x0f;
return (c - '0') & 0x0f;
}
// 从十六进制字符串到字节数组转换
public static byte[] HexString2Bytes(String hexstr) {
byte[] b = new byte[hexstr.length() / 2];
int j = 0;
for (int i = 0; i < b.length; i++) {
char c0 = hexstr.charAt(j++);
char c1 = hexstr.charAt(j++);
b[i] = (byte) ((parse(c0) << 4) | parse(c1));
}
return b;
}
/** *//**
* CBC解密
* @param key 密钥
* @param keyiv IV
* @param data Base64编码的密文
* @return明文
* @throws Exception
*/
public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data) throws Exception {
Key deskey = keyGenerator(new String(key));
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
IvParameterSpec ips = new IvParameterSpec(keyiv);
cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
byte[] bOut = cipher.doFinal(data);
return bOut;
}
public static void main(String[] args) throws Exception { byte[] key =
"6C4E60E55552386C759569836DC0F83869836DC0F838C0F7".getBytes();
byte[] keyiv = { 1, 2, 3, 4, 5, 6, 7, 8 };
byte[] data = "amigoxie".getBytes("UTF-8");
System.out.println("data.length=" + data.length);
System.out.println("CBC加密解密");
byte[] str5 = des3EncodeCBC(key, keyiv, data);
System.out.println(new
sun.misc.BASE64Encoder().encode(str5));
byte[] str6 = des3DecodeCBC(key, keyiv, str5);
System.out.println(new String(str6, "UTF-8"));
}
}。