加密,是以某種特殊的算法改變原有的信息數據,使得未受權的用戶即便得到了已加密的信息,但因不知解密的方法,仍然沒法瞭解信息的內容。html
package com.paic.java8; import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.Base64; import java.util.UUID; public class Base64Demo { public static void main(String args[]) { try { // 使用基本編碼 String bStr = "I am a hero!"; System.out.println("字符串:"+bStr); String base64encodedString = Base64.getEncoder().encodeToString(bStr.getBytes("utf-8")); System.out.println("基本(編碼) :" + base64encodedString); // 解碼 byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString); System.out.println("基本(解碼): " + new String(base64decodedBytes, "utf-8")); //----------------------- String urlStr = "TutorialsPoint?java8"; System.out.println("URL字符串:"+urlStr); base64encodedString = Base64.getUrlEncoder().encodeToString(urlStr.getBytes("utf-8")); System.out.println("URL(編碼) :" + base64encodedString); base64decodedBytes = Base64.getUrlDecoder().decode(base64encodedString); System.out.println("URL(解碼): " + new String(base64decodedBytes, "utf-8")); //--------------------------- StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < 10; ++i) { stringBuilder.append(UUID.randomUUID().toString()); } System.out.println("MIME字符串 :"+stringBuilder.toString()); byte[] mimeBytes = stringBuilder.toString().getBytes("utf-8"); String mimeEncodedString = Base64.getMimeEncoder().encodeToString(mimeBytes); System.out.println("MIME(編碼) :" + mimeEncodedString); base64decodedBytes = Base64.getMimeDecoder().decode(mimeEncodedString); System.out.println("MIME(解碼): " + new String(base64decodedBytes, "utf-8")); } catch (UnsupportedEncodingException e) { System.out.println("Error :" + e.getMessage()); } } }
字符串:I am a hero! 基本(編碼) :SSBhbSBhIGhlcm8h 基本(解碼): I am a hero! URL字符串:TutorialsPoint?java8 URL(編碼) :VHV0b3JpYWxzUG9pbnQ_amF2YTg= URL(解碼): TutorialsPoint?java8 MIME字符串 :ff3eb049-2440-4776-ba6d-becccda60c6f5def99b1-2009-433b-a09c-7fc393305e0641629364-0a92-4d5e-8c5d-1c5ad6a14025ec2ad8ce-2a51-4a0e-b633-ddbb9b2671a15a4fe3e9-7217-4209-a2f1-c478f29cf2dc591579bb-5e31-4984-b4c2-a960924e06e125b28902-aea3-4f76-bcd2-afe533a65cccb66a5eda-71e4-46ba-93fa-0ce685e7e67b9f704c87-34a0-441c-88fc-867a861d771d450d445d-a7ef-4309-b884-f787615f0512 MIME(編碼) :ZmYzZWIwNDktMjQ0MC00Nzc2LWJhNmQtYmVjY2NkYTYwYzZmNWRlZjk5YjEtMjAwOS00MzNiLWEw OWMtN2ZjMzkzMzA1ZTA2NDE2MjkzNjQtMGE5Mi00ZDVlLThjNWQtMWM1YWQ2YTE0MDI1ZWMyYWQ4 Y2UtMmE1MS00YTBlLWI2MzMtZGRiYjliMjY3MWExNWE0ZmUzZTktNzIxNy00MjA5LWEyZjEtYzQ3 OGYyOWNmMmRjNTkxNTc5YmItNWUzMS00OTg0LWI0YzItYTk2MDkyNGUwNmUxMjViMjg5MDItYWVh My00Zjc2LWJjZDItYWZlNTMzYTY1Y2NjYjY2YTVlZGEtNzFlNC00NmJhLTkzZmEtMGNlNjg1ZTdl NjdiOWY3MDRjODctMzRhMC00NDFjLTg4ZmMtODY3YTg2MWQ3NzFkNDUwZDQ0NWQtYTdlZi00MzA5 LWI4ODQtZjc4NzYxNWYwNTEy MIME(解碼): ff3eb049-2440-4776-ba6d-becccda60c6f5def99b1-2009-433b-a09c-7fc393305e0641629364-0a92-4d5e-8c5d-1c5ad6a14025ec2ad8ce-2a51-4a0e-b633-ddbb9b2671a15a4fe3e9-7217-4209-a2f1-c478f29cf2dc591579bb-5e31-4984-b4c2-a960924e06e125b28902-aea3-4f76-bcd2-afe533a65cccb66a5eda-71e4-46ba-93fa-0ce685e7e67b9f704c87-34a0-441c-88fc-867a861d771d450d445d-a7ef-4309-b884-f787615f0512
說明:java
一、以上是壞蛋不知密鑰狀況下,發送請求,第三方根據請求參數+密鑰生成sign與請求的sign比較;算法
注意:這裏128位是二進制,換算16進制32位apache
如:安全
package com.paic.java8; import org.apache.commons.codec.binary.Hex; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MDXDemo { public static void main(String[] args) { String screctKey = "123"; String content = "Hello"; encrypt(content,screctKey); } /** * 加密 * @param content * @param screctKey */ public static void encrypt(String content,String screctKey){ MessageDigest md5= null; MessageDigest md2= null; //內容 + 密鑰 //緣由:若是單單只是內容,攻擊方也是能夠經過MD5獲得sign1,拼接攻擊方不知到的密鑰,在攻擊方篡改內容後將獲得不一樣的sign2 //固然攻擊方能夠根據sign1解密從而得到密鑰 String src = content + screctKey; try { md5 = MessageDigest.getInstance("MD5"); md2 = MessageDigest.getInstance("MD2"); byte[] digest5 = md5.digest(src.getBytes()); byte[] digest2 = md2.digest(src.getBytes()); System.out.println("JDK MD5: "+ Hex.encodeHexString(digest5)); System.out.println("JDK MD2: "+ Hex.encodeHexString(digest2)); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } }
32位字符網絡
JDK MD5: d0aabe9a362cb2712ee90e04810902f3
JDK MD2: 014b1eb8d5557bb786b83a18c9fbbe2eapp
解密,在線上測試下:https://www.somd5.com/dom
安全性:SHA1所產生的摘要比MD5長32位。若兩種散列函數在結構上沒有任何問題的話,SHA1比MD5更安全ide
package com.paic.java8; import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.digest.DigestUtils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class SHAXDemo { public static void main(String[] args) { String content = "Hello"; jdkSHA1(content); ccsha(content); } /** * JDK實現方式(一樣是使用MessageDigest) * @param src */ public static void jdkSHA1(String src){ MessageDigest digest; try { digest = MessageDigest.getInstance("SHA"); digest.update(src.getBytes()); System.out.println("JDK SHA1:"+Hex.encodeHexString(digest.digest())); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } /** * cc的實現方式 * @param src */ public static void ccsha(String src){ System.out.println("CC SHA1:"+ DigestUtils.sha1Hex(src)); } //BC略... }
JDK SHA1:f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0
CC SHA1:f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0函數
含有密鑰的摘要算法,也有簡稱mac,密鑰不一樣摘要也不一樣
package com.paic.java8.encry; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.digest.DigestUtils; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; public class HmacDemo { public static void main(String[] args) { encrypt("Hello","aaaaaaaaaa"); } /** * JDK的實現方式 BC略 * @param content * @param key */ public static void encrypt(String content,String key){ SecretKey secretKey = getSecretKey(key); try { Mac mac= Mac.getInstance(secretKey.getAlgorithm()); //初始化mac mac.init(secretKey); byte[] hmacMD5Bytes=mac.doFinal(content.getBytes()); //jdk hmacMD5: bfb61695a42d5d16add45743a4e0eea4 System.out.println("jdk hmacMD5: "+Hex.encodeHexString(hmacMD5Bytes)); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } } /** * 獲取默認密鑰 * @return */ public static SecretKey getDefaultSecretKey() { SecretKey secretKey = null; //初始化KeyGenerator KeyGenerator keyGenerator = null; try { keyGenerator = KeyGenerator.getInstance("HmacMD5"); //產生密鑰 secretKey = keyGenerator.generateKey(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return secretKey; } /** * 自定義密鑰 * @param key * @return */ public static SecretKey getSecretKey(String key){ SecretKey secretKey = null; byte[] keyByteArr= null; try { //長度必須偶數 boolean flag = (null == key)? true : ((key.length()) & 1) != 0; if(flag){ throw new DecoderException("Key長度必須偶數"); } keyByteArr = Hex.decodeHex(key.toCharArray()); secretKey = new SecretKeySpec(keyByteArr,"HmacMD5"); } catch (DecoderException e) { e.printStackTrace(); } return secretKey; } }
/** * BC方式 */ public static void bcHmacMd5(){ String src = "Hello,World"; HMac hMac=new HMac(new MD5Digest()); hMac.init(new KeyParameter(org.bouncycastle.util.encoders.Hex.decode("aaaaaaaaaa"))); //須要十位密鑰 hMac.update(src.getBytes(),0,src.getBytes().length); byte[] hmacMD5=new byte[hMac.getMacSize()]; hMac.doFinal(hmacMD5, 0); System.out.println("bc hmacMD5: "+org.bouncycastle.util.encoders.Hex.toHexString(hmacMD5)); }
所謂對稱是說發送方和接收方的密鑰是同樣的,由於密鑰同樣因此安全性跟非對稱比較來講就不太安全了。
DES
package com.paic.java8.encry; import org.apache.commons.codec.binary.Hex; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.*; import javax.crypto.spec.DESKeySpec; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.Security; import java.security.spec.InvalidKeySpecException; public class DesSemo { public static void main(String[] args) { //jdkDES加密: cfa7121606a4413138d8d3781afeaa1c try { SecretKey key = getSecretKey("aaaabbbbcc"); byte[] content = jdkDESEncrypt("Hello DES", key); jdkDESDecrypt(content, key); bcDES(); } catch (InvalidKeyException e) { e.printStackTrace(); } } public static SecretKey getDefaultSecretKey() { KeyGenerator keyGenerator = null; SecretKey secretKey = null; try { keyGenerator = KeyGenerator.getInstance("DES"); keyGenerator.init(56); //指定key長度,同時也是密鑰長度(56位) secretKey = keyGenerator.generateKey(); //生成key的材料 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return secretKey; } /** * key 長度 > 8 * * @param key * @return * @throws InvalidKeyException */ public static SecretKey getSecretKey(String key) throws InvalidKeyException { SecretKey secretKey = null; byte[] keyByteArr = key.getBytes(); if (keyByteArr.length - 0 < 8) { throw new InvalidKeyException("Wrong key size"); } DESKeySpec desKeySpec = null; try { desKeySpec = new DESKeySpec(keyByteArr); SecretKeyFactory factory = SecretKeyFactory.getInstance("DES"); secretKey = factory.generateSecret(desKeySpec); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } return secretKey; } /** * DES 加密 * * @param content * @param key2 */ public static byte[] jdkDESEncrypt(String content, SecretKey key2) { //加密 Cipher cipher = null; byte[] result = null; try { //算法類型/工做方式/填充方式 cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); //指定爲加密模式 cipher.init(Cipher.ENCRYPT_MODE, key2); result = cipher.doFinal(content.getBytes()); //轉換爲十六進制 //desResult = Hex.encodeHexString(result); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } return result; } /** * 解密 * * @param encrypt * @param key */ public static void jdkDESDecrypt(byte[] encrypt, SecretKey key) { Cipher cipher = null; try { cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); //解密 cipher.init(Cipher.DECRYPT_MODE, key); //相同密鑰,指定爲解密模式 byte[] result = cipher.doFinal(encrypt); //根據加密內容解密 System.out.println("jdkDES解密: " + new String(result)); //轉換字符串 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } } /** * BC方式 */ public static void bcDES(){ String src = "Hello DES"; try { //經過改變provider的方式 Security.addProvider(new BouncyCastleProvider()); //生成key,使用bc須要在後面指定"BC" KeyGenerator keyGenerator=KeyGenerator.getInstance("DES","BC"); keyGenerator.getProvider(); keyGenerator.init(56); //指定key長度,同時也是密鑰長度 SecretKey secretKey = keyGenerator.generateKey(); //生成key的材料 byte[] key = secretKey.getEncoded(); //生成key //key轉換成密鑰 DESKeySpec desKeySpec=new DESKeySpec(key); SecretKeyFactory factory=SecretKeyFactory.getInstance("DES"); SecretKey key2 = factory.generateSecret(desKeySpec); //轉換後的密鑰 //加密 Cipher cipher=Cipher.getInstance("DES/ECB/PKCS5Padding"); //算法類型/工做方式/填充方式 cipher.init(Cipher.ENCRYPT_MODE, key2); byte[] result=cipher.doFinal(src.getBytes()); System.out.println("bcDES加密: "+Hex.encodeHexString(result)); //轉換爲十六進制 //解密 cipher.init(Cipher.DECRYPT_MODE,key2); //相同密鑰 result = cipher.doFinal(result); //根據加密內容解密 System.out.println("bcDES解密: "+new String(result)); //轉換字符串 } catch (Exception e) { e.printStackTrace(); } } }
package com.paic.java8.encry; import org.apache.commons.codec.binary.Hex; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import java.security.SecureRandom; import java.security.Security; public class Des3Demo { private static String src="Hello 3DES"; public static void main(String[] args) { } /** * jdk方式 */ public static void jdkDES(){ try { //生成key KeyGenerator keyGenerator=KeyGenerator.getInstance("DESede"); //keyGenerator.init(112); //3DES須要112 or 168位 keyGenerator.init(new SecureRandom()); //或者使用這種方式默認長度,無需指定長度 SecretKey secretKey = keyGenerator.generateKey(); //生成key的材料 byte[] key = secretKey.getEncoded(); //生成key //key轉換成密鑰 DESedeKeySpec desKeySpec=new DESedeKeySpec(key); SecretKeyFactory factory=SecretKeyFactory.getInstance("DESede"); SecretKey key2 = factory.generateSecret(desKeySpec); //轉換後的密鑰 //加密 Cipher cipher=Cipher.getInstance("DESede/ECB/PKCS5Padding"); //算法類型/工做方式/填充方式 cipher.init(Cipher.ENCRYPT_MODE, key2); //指定爲加密模式 byte[] result=cipher.doFinal(src.getBytes()); System.out.println("jdk3DES加密: "+ Hex.encodeHexString(result)); //轉換爲十六進制 //解密 cipher.init(Cipher.DECRYPT_MODE,key2); //相同密鑰,指定爲解密模式 result = cipher.doFinal(result); //根據加密內容解密 System.out.println("jdk3DES解密: "+new String(result)); //轉換字符串 } catch (Exception e) { e.printStackTrace(); } } /** * BC方式 */ public static void bcDES(){ try { //經過改變provider的方式,其餘操做同樣 Security.addProvider(new BouncyCastleProvider()); //生成key KeyGenerator keyGenerator=KeyGenerator.getInstance("DESede"); keyGenerator.init(new SecureRandom()); SecretKey secretKey = keyGenerator.generateKey(); //生成key的材料 byte[] key = secretKey.getEncoded(); //生成key //key轉換成密鑰 DESedeKeySpec desKeySpec=new DESedeKeySpec(key); SecretKeyFactory factory=SecretKeyFactory.getInstance("DESede"); SecretKey key2 = factory.generateSecret(desKeySpec); //轉換後的密鑰 //加密 Cipher cipher=Cipher.getInstance("DESede/ECB/PKCS5Padding"); //算法類型/工做方式/填充方式 cipher.init(Cipher.ENCRYPT_MODE, key2); //指定爲加密模式 byte[] result=cipher.doFinal(src.getBytes()); System.out.println("jdk3DES加密: "+Hex.encodeHexString(result)); //轉換爲十六進制 //解密 cipher.init(Cipher.DECRYPT_MODE,key2); //相同密鑰,指定爲解密模式 result = cipher.doFinal(result); //根據加密內容解密 System.out.println("jdk3DES解密: "+new String(result)); //轉換字符串 } catch (Exception e) { e.printStackTrace(); } } }
待續