在后台开发过程中,尤其是在做支付相关的开发时,需要用到加密相关的知识,今天我们就来讲一下加密中的对称加密与Java中的对称加密的应用。
对称加密,顾名思义,即在加密的过程是对称的,具体的加解密流程图如下:
可以看到,加密的时候,使用密钥将明文加密成明文,解密的时候,使用同一密钥将密文解密成明文,也就是说,双方在加解密的时候使用同一密钥即可。
在对称加密中,比较出名与常用的是两种加密标准,一种是DES对称加密,一种是现在常用的AES对称加密。
一、DES对称加密:
在DES加密中,有很多种加密方式,具体的可以看下图,需要注意的时,加解密双方需要使用同一种加密方式进行加解密:
其中JDK来实现DES加解密的示例代码为:
package com.happyheng.main;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import org.apache.commons.codec.binary.Hex;
public class DESUtils {
// 密钥
public static String key = "e945f1542a8c837c";
// 明文
public static String text = "hello des";
public static void main(String[] args) {
jdkDES(key);
}
public static void jdkDES(String key) {
try {
// 得到byte数组Key
byte[] bytesKey = Hex.decodeHex(key.toCharArray());
// (生成的key需要转换后才能使用)key转换
DESKeySpec desKeySpec = new DESKeySpec(bytesKey);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
Key convertSecretKey = factory.generateSecret(desKeySpec);
// 加密
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);
byte[] encryptResult = cipher.doFinal(text.getBytes());
System.out.println("jdk des encrypt:" + Hex.encodeHexString(encryptResult));
// 解密
cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);
byte[] decryptResult = cipher.doFinal(encryptResult);
System.out.println("jdk des decrypt:" + new String(decryptResult));
} catch (Exception e) {
e.printStackTrace();
}
}
}
可以看到,我们以16进制存储密钥,使用JDK中的Cipher类进行加解密
随着计算机系统能力的不断发展,DES的安全性比它刚出现时弱得多,所以现在推荐使用AES加密。
AES加密的标准如下:
其中JDK来实现AES加解密的示例代码为:
package com.happyheng.main;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
public class AESUtils {
public static String key = "fd980019fc95df40f0ed43731e11213c";
public static String text = "hello";
public static void main(String[] args) {
//byte[] key = getAESKey();
//System.out.println("生成的key为--"+Hex.encodeHexString(key));
jdkAES(key);
}
public static byte[] getAESKey() {
KeyGenerator keyGenerator;
try {
keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
SecretKey secretKey = keyGenerator.generateKey();
byte[] bytesKey = secretKey.getEncoded();
return bytesKey;
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static void jdkAES(String HexStringkey) {
try {
byte[] byteskey = Hex.decodeHex(HexStringkey.toCharArray());
//转换key
Key convertSecretKey = new SecretKeySpec(byteskey, "AES");
//加密
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);
byte[] encryptResult = cipher.doFinal(text.getBytes());
System.out.println("jdk des encrypt:" + Hex.encodeHexString(encryptResult));
// 解密
cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);
byte[] decryptResult = cipher.doFinal(encryptResult);
System.out.println("jdk des decrypt:" + new String(decryptResult));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
可以看到,我们同样使用JDK中的Cipher类进行加解密,其中代码中的getAESKey()方法可以得到128位的密钥。