基本介紹
對稱加密算法是現在應用范圍最廣,使用頻率最高的加密算法。
對稱的原因:
加密密鑰 = 解密密鑰,加密運算是解密運算的逆運算。
對稱加密算法是初等的加密算法,從安全性上說,不是很高。
常用的對稱加密算法:
DES(3DES),AES,PBE,IDEA等。
DES
DES(Data Encryption Standard):數據加密標準(已經被破解)
例子:
package
com.timliu.security.symmetric_encryptionimport java
.security.Key
import java
.security.Securityimport javax
.crypto.Cipher
import javax
.crypto.KeyGenerator
import javax
.crypto.SecretKey
import javax
.crypto.SecretKeyFactory
import javax
.crypto.spec.DESKeySpecimport org
.apache.commons.codec.binary.Hex
import org
.bouncycastle.jce.provider.BouncyCastleProviderpublic class DESTest {public static final String src =
"hello world"public static void main(String[] args) {jdkDES()bcDES()}// 用jdk實現:public static void jdkDES() {try {// 獲取KEY生成器KeyGenerator keyGenerator = KeyGenerator
.getInstance(
"DES")keyGenerator
.init(
56)// 產生KEYSecretKey secretKey = keyGenerator
.generateKey()// 獲取KEYbyte[] bytesKey = secretKey
.getEncoded()// 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[] result = cipher
.doFinal(src
.getBytes())System
.out.println(
"jdk des encrypt:" + Hex
.encodeHexString(result))// 解密cipher
.init(Cipher
.DECRYPT_MODE, convertSecretKey)result = cipher
.doFinal(result)System
.out.println(
"jdk des decrypt:" + new String(result))} catch (Exception e) {e
.printStackTrace()}}// 用bouncy castle實現:public static void bcDES() {try {Security
.addProvider(new BouncyCastleProvider())// 獲取KEY生成器KeyGenerator keyGenerator = KeyGenerator
.getInstance(
"DES",
"BC")keyGenerator
.getProvider()keyGenerator
.init(
56)// 產生KEYSecretKey secretKey = keyGenerator
.generateKey()// 獲取KEYbyte[] bytesKey = secretKey
.getEncoded()// 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[] result = cipher
.doFinal(src
.getBytes())System
.out.println(
"bc des encrypt:" + Hex
.encodeHexString(result))// 解密cipher
.init(Cipher
.DECRYPT_MODE, convertSecretKey)result = cipher
.doFinal(result)System
.out.println(
"bc des decrypt:" + new String(result))} catch (Exception e) {e
.printStackTrace()}}}
運行結果:
DES應用場景
3DES
3重DES的好處:
1. 密鑰長度增強
2. 迭代次數提高
例子:
package
com.timliu.security.symmetric_encryptionimport java
.security.Key
import java
.security.SecureRandom
import java
.security.Securityimport javax
.crypto.Cipher
import javax
.crypto.KeyGenerator
import javax
.crypto.SecretKey
import javax
.crypto.SecretKeyFactory
import javax
.crypto.spec.DESKeySpec
import javax
.crypto.spec.DESedeKeySpecimport org
.apache.commons.codec.binary.Hex
import org
.bouncycastle.jce.provider.BouncyCastleProviderpublic class DES3Test {public static final String src =
"hello world"public static void main(String[] args) {jdk3DES()bc3DES()}// 用jdk實現:public static void jdk3DES() {try {// 獲取KEY生成器KeyGenerator keyGenerator = KeyGenerator
.getInstance(
"DESede")// 必須長度是:
112或
168// keyGenerator
.init(
168)keyGenerator
.init(new SecureRandom())// 產生KEYSecretKey secretKey = keyGenerator
.generateKey()// 獲取KEYbyte[] bytesKey = secretKey
.getEncoded()// KEY轉換DESedeKeySpec desKeySpec = new DESedeKeySpec(bytesKey)SecretKeyFactory factory = SecretKeyFactory
.getInstance(
"DESede")Key convertSecretKey = factory
.generateSecret(desKeySpec)// 加密Cipher cipher = Cipher
.getInstance(
"DESede/ECB/PKCS5Padding")cipher
.init(Cipher
.ENCRYPT_MODE, convertSecretKey)byte[] result = cipher
.doFinal(src
.getBytes())System
.out.println(
"jdk 3des encrypt:"+ Hex
.encodeHexString(result))// 解密cipher
.init(Cipher
.DECRYPT_MODE, convertSecretKey)result = cipher
.doFinal(result)System
.out.println(
"jdk 3des decrypt:" + new String(result))} catch (Exception e) {e
.printStackTrace()}}// 用bouncy castle實現:public static void bc3DES() {try {Security
.addProvider(new BouncyCastleProvider())// 獲取KEY生成器KeyGenerator keyGenerator = KeyGenerator
.getInstance(
"DESede",
"BC")keyGenerator
.getProvider()keyGenerator
.init(
168)// 產生KEYSecretKey secretKey = keyGenerator
.generateKey()// 獲取KEYbyte[] bytesKey = secretKey
.getEncoded()// KEY轉換DESedeKeySpec desKeySpec = new DESedeKeySpec(bytesKey)SecretKeyFactory factory = SecretKeyFactory
.getInstance(
"DESede")Key convertSecretKey = factory
.generateSecret(desKeySpec)// 加密Cipher cipher = Cipher
.getInstance(
"DESede/ECB/PKCS5Padding")cipher
.init(Cipher
.ENCRYPT_MODE, convertSecretKey)byte[] result = cipher
.doFinal(src
.getBytes())System
.out.println(
"bc 3des encrypt:" + Hex
.encodeHexString(result))// 解密cipher
.init(Cipher
.DECRYPT_MODE, convertSecretKey)result = cipher
.doFinal(result)System
.out.println(
"bc 3des decrypt:" + new String(result))} catch (Exception e) {e
.printStackTrace()}}}
AES
產生的原因:
1. DES的算法有些漏洞
2. 3DES的算法相對來說效率比較低
AES是目前使用最多的對稱加密算法。
AES的優勢之一是至今尚未被破解。
AES通常用于移動通信系統加密以及基于SSH協議的軟件(SSH Client,secureCRT)。
無政策限制權限文件是指:因為某些國家的進口管制限制,Java發布的運行環境包中的加解密有一定的限制。
例子:
package
com.timliu.security.symmetric_encryptionimport java
.security.Key
import java
.security.Securityimport javax
.crypto.Cipher
import javax
.crypto.KeyGenerator
import javax
.crypto.SecretKey
import javax
.crypto.spec.SecretKeySpecimport org
.apache.commons.codec.binary.Hex
import org
.bouncycastle.jce.provider.BouncyCastleProviderpublic class AESTest {public static final String src =
"hello world"public static void main(String[] args) {jdkAES()bcAES()}// 用jdk實現:public static void jdkAES() {try {// 獲取KEY生成器KeyGenerator keyGenerator = KeyGenerator
.getInstance(
"AES")keyGenerator
.init(
128)// 產生KEYSecretKey secretKey = keyGenerator
.generateKey()// 獲取KEYbyte[] keyBytes = secretKey
.getEncoded()// KEY轉換Key key = new SecretKeySpec(keyBytes,
"AES")// 加密Cipher cipher = Cipher
.getInstance(
"AES/ECB/PKCS5Padding")cipher
.init(Cipher
.ENCRYPT_MODE, key)byte[] result = cipher
.doFinal(src
.getBytes())System
.out.println(
"jdk aes encrypt:" + Hex
.encodeHexString(result))// 解密cipher
.init(Cipher
.DECRYPT_MODE, key)result = cipher
.doFinal(result)System
.out.println(
"jdk aes decrypt:" + new String(result))} catch (Exception e) {e
.printStackTrace()}}// 用bouncy castle實現:public static void bcAES() {try {Security
.addProvider(new BouncyCastleProvider())// 獲取KEY生成器KeyGenerator keyGenerator = KeyGenerator
.getInstance(
"AES",
"BC")keyGenerator
.getProvider()keyGenerator
.init(
128)// 產生KEYSecretKey secretKey = keyGenerator
.generateKey()// 獲取KEYbyte[] keyBytes = secretKey
.getEncoded()// KEY轉換Key key = new SecretKeySpec(keyBytes,
"AES")// 加密Cipher cipher = Cipher
.getInstance(
"AES/ECB/PKCS5Padding")cipher
.init(Cipher
.ENCRYPT_MODE, key)byte[] result = cipher
.doFinal(src
.getBytes())System
.out.println(
"bc aes encrypt:" + Hex
.encodeHexString(result))// 解密cipher
.init(Cipher
.DECRYPT_MODE, key)result = cipher
.doFinal(result)System
.out.println(
"bc aes decrypt:" + new String(result))} catch (Exception e) {e
.printStackTrace()}}}
運行結果:
應用場景:
PBE
PBE算法結合了消息摘要算法和對稱加密算法的優點。
PBE算法并不是新的算法,而是對已有的對稱加密算法和消息摘要算法的整合。
PBE(Password Based Encryption):基于口令的加密
口令是用戶自己輸入的,但通常口令不會很復雜。同時為了防止窮舉的方式破解口令,還要對口令進行加鹽(也就是在口令中加入隨機數)。
PBE算法實際上就是,采用口令替代了之前對稱加密算法中生成的KEY。
例子:
package com.timliu.security.symmetric_encryption;
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import org.apache.commons.codec.binary.Hex;
public class PBETest {public static final String src =
"hello world";
public static void main(String[] args) {jdkPBE();}
public static void jdkPBE(){
try {SecureRandom random =
new SecureRandom();
byte[] salt = random.generateSeed(
8);String password =
"zhangyaohui";PBEKeySpec pbeKeySpec =
new PBEKeySpec(password.toCharArray()); SecretKeyFactory factory = SecretKeyFactory.getInstance(
"PBEWITHMD5andDES");Key key = factory.generateSecret(pbeKeySpec);PBEParameterSpec pbeParameterSpac =
new PBEParameterSpec(salt,
100);Cipher cipher = Cipher.getInstance(
"PBEWITHMD5andDES");cipher.init(Cipher.ENCRYPT_MODE, key, pbeParameterSpac);
byte[] result = cipher.doFinal(src.getBytes());System.out.println(
"jdk pbe encrypt:" + Hex.encodeHexString(result));cipher.init(Cipher.DECRYPT_MODE, key, pbeParameterSpac);result = cipher.doFinal(result);System.out.println(
"jdk pbe decrypt:" +
new String(result));}
catch (Exception e) {e.printStackTrace();}}}
運行結果:
PBE應用場景:
最后問題:
以上的代碼中加密和解密是在同一方的,如果加密解密不在同一方怎么辦?
把密鑰發送給對方(但是密鑰通過網絡發送很容易被截取到,可以將密鑰進行處理)
總結
以上是生活随笔為你收集整理的对称加密算法---加密学习笔记(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。