前言
之前对非对称加密作了介绍(),现对对称加密作个简单介绍。
对称加密算法
能通过相同的密钥对报文进行加密、解密的算法,叫对称加密算法。
比如,客户端,将一段报文通过密钥加密成密文,发送密文给服务端,服务端收到密文,通过相同的密钥解密,还原报文。常用的对称加密算法:DES
特点:
- 通过相同的密钥对报文进行加密、解密。所以,需要保证密钥的保密。
- 计算速度快。所以,经常与计算速度慢的
非对称加密算法
一起使用,形成混合加密(后续博文描述)。
为什么要有密钥
我们有加密算法,为什么要有密钥?
答:加密算法只是一种算法(可视作一套逻辑),通常为大家所知,比如DES。如果一段报文,通过大家熟知的逻辑加密,那么其他人也能通过相应的逻辑解密,这样意义不大。所以就有密钥,相当于算法的密码,算法逻辑加上密钥公共将报文加密成密文,相应的,需通过算法逻辑和密钥才能正确解密。危险
最常见的破解加密算法的手段是枚举攻击。由于大家都知道算法的逻辑,通过枚举密钥的所有可能性尝试解码。所以,密钥的位数决定了枚举攻击的难度,密钥位数越多,越难枚举出所有的可能性破解,当然,我们加解密的计算速度也有相应的影响。随着现代计算机计算速度提升,密钥的位数也在提升。
简单的例子
import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.spec.InvalidKeySpecException;import java.util.Base64;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESKeySpec;import org.junit.Test;public class DESUtils { /** * 加密 * @param data 加密的数据 * @param key 密钥 * @return 加密后的数据 */ public static byte[] encrypt(byte[] data, byte[] key) { try { DESKeySpec desKeySpec = new DESKeySpec(key); SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); return cipher.doFinal(data); } catch (InvalidKeyException e) { throw new RuntimeException("无效的Key值"); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("无DES算法"); } catch (InvalidKeySpecException e) { throw new RuntimeException("无效的KeySpec"); } catch (NoSuchPaddingException e) { throw new RuntimeException("无Padding"); } catch (IllegalBlockSizeException e) { throw new RuntimeException(e); } catch (BadPaddingException e) { throw new RuntimeException(e); } } /** * 解密 * @param data 解密前的数据 * @param key 密钥 * @return 解密后的数据 */ public static byte[] decrypt(byte[] data, byte[] key) { try { DESKeySpec desKeySpec = new DESKeySpec(key); SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, secretKey); return cipher.doFinal(data); } catch (InvalidKeyException e) { throw new RuntimeException("无效的Key值"); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("无DES算法"); } catch (InvalidKeySpecException e) { throw new RuntimeException("无效的KeySpec"); } catch (NoSuchPaddingException e) { throw new RuntimeException("无Padding"); } catch (IllegalBlockSizeException e) { throw new RuntimeException(e); } catch (BadPaddingException e) { throw new RuntimeException(e); } } @Test public void encryptTest() { System.out.println(Base64.getEncoder().encodeToString(DESUtils.encrypt("hello".getBytes(), "12345678".getBytes()))); } @Test public void decryptTest() { System.out.println(new String(DESUtils.decrypt(Base64.getDecoder().decode("uhbGoCVxJa8="), "12345678".getBytes()))); } }