亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

總結(jié)Java常用到的六個加密技術(shù)和代碼

 更新時間:2016年07月16日 14:36:14   投稿:daisy  
大家要記住現(xiàn)代密碼學最重要的原則柯克霍夫原則:數(shù)據(jù)的安全基于密鑰而不是算法的保密。也就是說即使密碼系統(tǒng)的任何細節(jié)已為人悉知,只要密匙未洩漏,它也應是安全的。這篇文章給大家介紹了6個常用的加密技術(shù)和代碼。

加密,是以某種特殊的算法改變原有的信息數(shù)據(jù),使得未授權(quán)的用戶即使獲得了已加密的信息,但因不知解密的方法,仍然無法了解信息的內(nèi)容。大體上分為雙向加密和單向加密,而雙向加密又分為對稱加密和非對稱加密(有些資料將加密直接分為對稱加密和非對稱加密)。

雙向加密大體意思就是明文加密后形成密文,可以通過算法還原成明文。而單向加密只是對信息進行了摘要計算,不能通過算法生成明文,單向加密從嚴格意思上說不能算是加密的一種,應該算是摘要算法吧。

具體來說:
系統(tǒng)必須可用,非數(shù)學上不可譯碼。
系統(tǒng)不一定要保密,可以輕易落入敵人手中。
密匙必須可以不經(jīng)書寫的資料交換和記憶,且雙方可以改變密匙。
系統(tǒng)可以用于電訊。
系統(tǒng)可以轉(zhuǎn)移位置,它的功能必須不用經(jīng)過幾個人之手才可達到。
系統(tǒng)容易使用,不要求使用者的腦力過份操勞或有很多的規(guī)則。

一、主要的加密方式代碼提供方
JDK:代碼在java安裝目錄下的jre\lib\jce.jar包里;
CC:Apache公司提供的org.apache.commons.codec
主頁: http://commons.apache.org/proper/commons-codec/
BC:org.bouncecastle
主頁: http://www.bouncycastle.org/java.html
基本常用的使用JDK就夠了。

二、Base64算法
1、從現(xiàn)在加密算法的復雜性來看Base64這種都不好意思說自己是加密,不過對于完全不懂計算機的人來說也夠用了。采用Base64編碼具有不可讀性,即所編碼的數(shù)據(jù)不會被人用肉眼所直接看到。
Base64編碼一般用于url的處理,或者說任何你不想讓普通人一眼就知道是啥的東西都可以用Base64編碼處理后再發(fā)布在網(wǎng)絡上。

package com.amuro.strategy.base64;

import java.util.Base64;

import com.amuro.strategy.IStrategy;

/**
 * Base64算法基于64個基本字符,加密后的string中只包含這64個字符
 * @author Amuro
 *
 */
public class Base64Strategy implements IStrategy
{
 public String encode(String src)
 {
 byte[] encodeBytes = Base64.getEncoder().encode(src.getBytes());
 return new String(encodeBytes);
 }

 public String decode(String src)
 {
 byte[] decodeBytes = Base64.getDecoder().decode(src.getBytes());
 return new String(decodeBytes);
 }
}

2、Base64編碼對應關(guān)系表

三、消息摘要算法(Message Digest)
消息摘要(Message Digest)又稱為數(shù)字摘要(Digital Digest)。它是一個唯一對應一個消息或文本的固定長度的值,它由一個單向Hash加密函數(shù)對消息進行作用而產(chǎn)生。HASH函數(shù)的抗沖突性使得如果一段明文稍有變化,哪怕只更改該段落的一個字母,通過哈希算法作用后都將產(chǎn)生不同的值。而HASH算法的單向性使得要找到哈希值相同的兩個不同的輸入消息,在計算上是不可能的。所以數(shù)據(jù)的哈希值,即消息摘要,可以檢驗數(shù)據(jù)的完整性。
用大白話來說,任何一段數(shù)據(jù)應該都和人一樣是唯一的,唯一的標識是什么,人類的話目前就是指紋,而數(shù)據(jù)的指紋是什么呢?沒錯,就是消息摘要算法產(chǎn)生的這一段String。比如我們在注冊網(wǎng)站的時候,客戶端向服務器傳輸?shù)?,應該是我們輸入的密碼進行消息摘要處理后的內(nèi)容,這樣就算服務器被攻破,Hack也無法知道用戶真實的密碼是什么。不過有說現(xiàn)在MD5和SHA已經(jīng)被攻破了,具體大家可以谷歌。
1、MD5

package com.amuro.strategy.message_digest;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

/**
 * 消息摘要算法
 * @author Amuro
 *
 */
public class MD5Strategy implements IStrategy
{

 public String encode(String src)
 {
 try
 {
  MessageDigest md = MessageDigest.getInstance("MD5");
  byte[] encodeBytes = md.digest(src.getBytes());

  return Hex.encodeHexString(encodeBytes);
 }
 catch (NoSuchAlgorithmException e)
 {
  e.printStackTrace();
 }
 return null;
 }

 public String decode(String src)
 {
 throw new RuntimeException("MD5 no decode");
 }

}

2、SHA

package com.amuro.strategy.message_digest;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

/**
 * 安全散列算法
 * @author Amuro
 *
 */
public class SHAStrategy implements IStrategy
{

 public String encode(String src)
 {
 try
 {
  MessageDigest md = MessageDigest.getInstance("SHA");
  md.update(src.getBytes());
  return Hex.encodeHexString(md.digest());
 }
 catch (NoSuchAlgorithmException e)
 {
  e.printStackTrace();
 }
 return null;
 }

 public String decode(String src)
 {
 throw new RuntimeException("SHA no decode");
 }

}

四、對稱加密
采用單鑰密碼系統(tǒng)的加密方法,同一個密鑰可以同時用作信息的加密和解密,這種加密方法稱為對稱加密,也稱為單密鑰加密。而因為加密和解密都使用同一個密鑰,如何把密鑰安全地傳遞到解密者手上就成了必須要解決的問題。當然,安全性較低帶來的優(yōu)點就是優(yōu)計算量小、加密速度快、加密效率高。
然并卵,現(xiàn)代計算機對這種級別的計算量早就不care了,安全才是最重要的。
1、DES
DES,全稱為“Data Encryption Standard”,中文名為“數(shù)據(jù)加密標準”,是一種使用密鑰加密的塊算法。DES 算法為密碼體制中的對稱密碼體制,又被稱為美國數(shù)據(jù)加密標準,是 1972 年美國 IBM 公司研制的對稱密碼體制加密算法。 明文按 64 位進行分組,密鑰長 64 位,密鑰事實上是 56 位參與 DES 運算(第8、16、24、32、40、48、56、64 位是校驗位, 使得每個密鑰都有奇數(shù)個 1)分組后的明文組和 56 位的密鑰按位替代或交換的方法形成密文組的加密方法。

package com.amuro.strategy.des;

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;

import com.amuro.strategy.IStrategy;

/**
 * 
 * @author Amuro
 *
 */
public class DESStrategy implements IStrategy
{
 private Cipher cipher;
 private SecretKey generateKey;

 public String encode(String src)
 {
 try
 {
  KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
  keyGenerator.init(56);//size
  SecretKey secretKey = keyGenerator.generateKey();
  byte[] keyBytes = secretKey.getEncoded();

  DESKeySpec desKeySpec = new DESKeySpec(keyBytes);
  SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
  generateKey = secretKeyFactory.generateSecret(desKeySpec);

  cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
  cipher.init(Cipher.ENCRYPT_MODE, generateKey);
  byte[] resultBytes = cipher.doFinal(src.getBytes());

  return Hex.encodeHexString(resultBytes);
 }
 catch (Exception e)
 {
  e.printStackTrace();
 }

 return null;
 }

 public String decode(String src)
 {
 try
 {
  cipher.init(Cipher.DECRYPT_MODE, generateKey);
  byte[] result = Hex.decodeHex(src.toCharArray());
  return new String(cipher.doFinal(result));
 }
 catch(Exception e)
 {
  e.printStackTrace();
 }

 return null;
 }

}

2、3DES3DES,也就是“Triple DES”,中文名“三重數(shù)據(jù)加密算法”,它相當于是對每個數(shù)據(jù)塊應用三次 DES 加密算法。由于計算機運算能力的增強,原版 DES 密碼的密鑰長度變得容易被暴力破解;3DES 即是設計用來提供一種相對簡單的方法,即通過增加 DES 的密鑰長度來避免類似的攻擊,而不是設計一種全新的塊密碼算法。

package com.amuro.strategy.des;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

public class _3DESStrategy implements IStrategy
{
 private Cipher cipher;
 private SecretKey generateKey;

 public String encode(String src)
 {
 try
 {
  KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
  keyGenerator.init(168);//size
  SecretKey secretKey = keyGenerator.generateKey();
  byte[] keyBytes = secretKey.getEncoded();

  DESedeKeySpec desKeySpec = new DESedeKeySpec(keyBytes);
  SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DESede");
  generateKey = secretKeyFactory.generateSecret(desKeySpec);

  cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
  cipher.init(Cipher.ENCRYPT_MODE, generateKey);
  byte[] resultBytes = cipher.doFinal(src.getBytes());

  return Hex.encodeHexString(resultBytes);
 }
 catch (Exception e)
 {
  e.printStackTrace();
 }

 return null;
 }

 public String decode(String src)
 {
 try
 {
  cipher.init(Cipher.DECRYPT_MODE, generateKey);
  byte[] result = Hex.decodeHex(src.toCharArray());
  return new String(cipher.doFinal(result));
 }
 catch(Exception e)
 {
  e.printStackTrace();
 }

 return null;
 }
}

3、AESAES,全稱為“Advanced Encryption Standard”,中文名“高級加密標準”,在密碼學中又稱 Rijndael 加密法,是美國聯(lián)邦政府采用的一種區(qū)塊加密標準。AES 加密算法作為新一代的數(shù)據(jù)加密標準匯聚了強安全性、高性能、高效率、易用和靈活等優(yōu)點。AES 設計有三個密鑰長度:128,192,256 位。相對而言,AES 的 128 密鑰比 DES 的 56 密鑰強了 1021 倍。

package com.amuro.strategy.des;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

public class AESStrategy implements IStrategy
{
 private Cipher cipher;
 private SecretKey generateKey;

 public String encode(String src)
 {
 try
 {
  KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
  keyGenerator.init(128);//size
  SecretKey secretKey = keyGenerator.generateKey();
  byte[] keyBytes = secretKey.getEncoded();

  generateKey = new SecretKeySpec(keyBytes, "AES");

  cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
  cipher.init(Cipher.ENCRYPT_MODE, generateKey);
  byte[] resultBytes = cipher.doFinal(src.getBytes());

  return Hex.encodeHexString(resultBytes);
 }
 catch (Exception e)
 {
  e.printStackTrace();
 }

 return null;
 }

 public String decode(String src)
 {
 try
 {
  cipher.init(Cipher.DECRYPT_MODE, generateKey);
  byte[] result = Hex.decodeHex(src.toCharArray());
  return new String(cipher.doFinal(result));
 }
 catch(Exception e)
 {
  e.printStackTrace();
 }

 return null;
 }
}

4、PBE
PBE,全稱為“Password Base Encryption”,中文名“基于口令加密”,是一種基于密碼的加密算法,其特點是使用口令代替了密鑰,而口令由用戶自己掌管,采用隨機數(shù)雜湊多重加密等方法保證數(shù)據(jù)的安全性。
PBE算法沒有密鑰的概念,把口令當做密鑰了。因為密鑰長短影響算法安全性,還不方便記憶,這里我們直接換成我們自己常用的口令就大大不同了,便于我們的記憶。但是單純的口令很容易被字典法給窮舉出來,所以我們這里給口令加了點“鹽”,這個鹽和口令組合,想破解就難了。同時我們將鹽和口令合并后用消息摘要算法進行迭代很多次來構(gòu)建密鑰初始化向量的基本材料,使破譯更加難了。

package com.amuro.strategy.pbe;

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

/**
 * 基于口令的加密(password),對稱 + 消息摘要
 * @author Amuro
 *
 */
public class PBEStrategy implements IStrategy
{
 private Cipher cipher;
 private SecretKey generateKey;
 private PBEParameterSpec pbeParameterSpec;

 public String encode(String src)
 {
 try
 {
  SecureRandom secureRandom = new SecureRandom();
  byte[] salt = secureRandom.generateSeed(8);

  String password = "amuro";
  PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
  SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBEWITHMD5andDES");
  generateKey = secretKeyFactory.generateSecret(pbeKeySpec);

  pbeParameterSpec = new PBEParameterSpec(salt, 100);
  cipher = Cipher.getInstance("PBEWITHMD5andDES");
  cipher.init(Cipher.ENCRYPT_MODE, generateKey, pbeParameterSpec);
  byte[] resultBytes = cipher.doFinal(src.getBytes());
  return Hex.encodeHexString(resultBytes);
 }
 catch(Exception e)
 {
  e.printStackTrace();
 }

 return null;
 }

 public String decode(String src)
 {
 try
 {
  cipher.init(Cipher.DECRYPT_MODE, generateKey, pbeParameterSpec);
  byte[] result = Hex.decodeHex(src.toCharArray());
  return new String(cipher.doFinal(result));
 }
 catch(Exception e)
 {
  e.printStackTrace();
 }

 return null;
 }

}

五、非對稱加密
非對稱加密算法需要兩個密鑰來進行加密和解密,分別是公鑰和私鑰。需要注意的一點,這個公鑰和私鑰必須是一對的,如果用公鑰對數(shù)據(jù)進行加密,那么只有使用對應的私鑰才能解密,反之亦然。由于加密和解密使用的是兩個不同的密鑰,因此,這種算法叫做非對稱加密算法。
1、RSA
其實,在早在 1978 年的時候,RSA就已經(jīng)出現(xiàn)了,它是第一個既能用于數(shù)據(jù)加密也能用于數(shù)字簽名的算法。它易于理解和操作,也很流行。其原理就如上面的工作過程所述。RSA 算法基于一個十分簡單的數(shù)論事實:將兩個大素數(shù)相乘十分容易,但是想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰。

package com.amuro.strategy.asymmetric;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

public class RSAStrategy implements IStrategy
{
 private RSAPublicKey rsaPublicKey;
 private RSAPrivateKey rsaPrivateKey;

 public String encode(String src)
 {
 try
 {
  //初始化密鑰
  KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
  keyPairGenerator.initialize(512);
  KeyPair keyPair = keyPairGenerator.generateKeyPair();
  rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
  rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();

  //私鑰加密 公鑰解密
  PKCS8EncodedKeySpec pkcs8EncodedKeySpec 
  = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
  Cipher cipher = Cipher.getInstance("RSA");
  cipher.init(Cipher.ENCRYPT_MODE, privateKey);
  byte[] resultBytes = cipher.doFinal(src.getBytes());

  //私鑰解密 公鑰加密
//  X509EncodedKeySpec x509EncodedKeySpec =
//   new X509EncodedKeySpec(rsaPublicKey.getEncoded());
//  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//  PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
//  Cipher cipher = Cipher.getInstance("RSA");
//  cipher.init(Cipher.ENCRYPT_MODE, publicKey);
//  byte[] resultBytes = cipher.doFinal(src.getBytes());

  return Hex.encodeHexString(resultBytes);
 }
 catch(Exception e)
 {
  e.printStackTrace();
 }

 return null;
 }

 public String decode(String src)
 {
 try
 {
  //私鑰加密 公鑰解密
  X509EncodedKeySpec x509EncodedKeySpec =
   new X509EncodedKeySpec(rsaPublicKey.getEncoded());
  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
  Cipher cipher = Cipher.getInstance("RSA");
  cipher.init(Cipher.DECRYPT_MODE, publicKey);
  byte[] resultBytes = cipher.doFinal(Hex.decodeHex(src.toCharArray()));

  //私鑰解密 公鑰加密
//  PKCS8EncodedKeySpec pkcs8EncodedKeySpec 
//  = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
//  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//  PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
//  Cipher cipher = Cipher.getInstance("RSA");
//  cipher.init(Cipher.DECRYPT_MODE, privateKey);
//  byte[] resultBytes = cipher.doFinal(Hex.decodeHex(src.toCharArray()));

  return new String(resultBytes);
 }
 catch(Exception e)
 {
  e.printStackTrace();
 }
 return null;
 }

}

2、DH算法
DH,全稱為“Diffie-Hellman”,他是一種確保共享KEY安全穿越不安全網(wǎng)絡的方法,也就是常說的密鑰一致協(xié)議。由公開密鑰密碼體制的奠基人Diffie和Hellman所提出的一種思想。簡單的說就是允許兩名用戶在公開媒體上交換信息以生成“一致”的、可以共享的密鑰。也就是由甲方產(chǎn)出一對密鑰(公鑰、私鑰),乙方依照甲方公鑰產(chǎn)生乙方密鑰對(公鑰、私鑰)。
以此為基線,作為數(shù)據(jù)傳輸保密基礎,同時雙方使用同一種對稱加密算法構(gòu)建本地密鑰(SecretKey)對數(shù)據(jù)加密。這樣,在互通了本地密鑰(SecretKey)算法后,甲乙雙方公開自己的公鑰,使用對方的公鑰和剛才產(chǎn)生的私鑰加密數(shù)據(jù),同時可以使用對方的公鑰和自己的私鑰對數(shù)據(jù)解密。不單單是甲乙雙方兩方,可以擴展為多方共享數(shù)據(jù)通訊,這樣就完成了網(wǎng)絡交互數(shù)據(jù)的安全通訊!

package com.amuro.strategy.asymmetric;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Objects;

import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

public class DHStrategy implements IStrategy
{
 private Cipher cipher;
 private SecretKey receiverSecretKey;

 public String encode(String src)
 {
 try
 {
  //初始化發(fā)送方密鑰
  KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");
  senderKeyPairGenerator.initialize(512);
  KeyPair senderkeyPair = senderKeyPairGenerator.generateKeyPair();
  PrivateKey senderPrivateKey = senderkeyPair.getPrivate();
  byte[] senderPublicKeyBytes = senderkeyPair.getPublic().getEncoded();//發(fā)送方的公鑰

  //初始化接收方密鑰,用發(fā)送方的公鑰
  KeyFactory receiverKeyFactory = KeyFactory.getInstance("DH");
  X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKeyBytes);
  PublicKey receiverPublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec);
  DHParameterSpec dhParameterSpec = 
   ((DHPublicKey)receiverPublicKey).getParams();
  KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH");
  receiverKeyPairGenerator.initialize(dhParameterSpec);
  KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair();
  PrivateKey receiverPrivateKey = receiverKeyPair.getPrivate();
  byte[] receiverPublicKeyBytes = receiverKeyPair.getPublic().getEncoded();

  KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH");
  receiverKeyAgreement.init(receiverPrivateKey);
  receiverKeyAgreement.doPhase(receiverPublicKey, true);
  receiverSecretKey = receiverKeyAgreement.generateSecret("DES");

  //發(fā)送方拿到接收方的public key就可以做加密了
  KeyFactory senderKeyFactory = KeyFactory.getInstance("DH");
  x509EncodedKeySpec = new X509EncodedKeySpec(receiverPublicKeyBytes);
  PublicKey senderPublicKey = senderKeyFactory.generatePublic(x509EncodedKeySpec);
  KeyAgreement senderKeyAgreement = KeyAgreement.getInstance("DH");
  senderKeyAgreement.init(senderPrivateKey);
  senderKeyAgreement.doPhase(senderPublicKey, true);
  SecretKey senderSecretKey = senderKeyAgreement.generateSecret("DES");

  if(Objects.equals(receiverSecretKey, senderSecretKey))
  {
  cipher = Cipher.getInstance("DES");
  cipher.init(Cipher.ENCRYPT_MODE, senderSecretKey);
  byte[] result = cipher.doFinal(src.getBytes());
  return Hex.encodeHexString(result);
  }

 }
 catch(Exception e)
 {
  e.printStackTrace();
 }

 return null;
 }

 public String decode(String src)
 {
 try
 {
  cipher.init(Cipher.DECRYPT_MODE, receiverSecretKey);
  byte[] result = Hex.decodeHex(src.toCharArray());
  return new String(cipher.doFinal(result));
 }
 catch(Exception e)
 {
  e.printStackTrace();
 }

 return null;
 }

}

六、數(shù)字簽名證書
非對稱加密已經(jīng)灰常安全了,但是還有一個破綻:
服務器A公布了自己的公鑰,我的電腦是用服務器A的公鑰加密數(shù)據(jù)后再發(fā)給服務器A的;這時候服務器B侵入了我的電腦,把我用來加密的公鑰換成了它的公鑰,于是我發(fā)出去的數(shù)據(jù)就會被服務器B的私鑰破解了。腫么防止公鑰被篡改呢?
對,我們想到了前面的消息摘要,服務器A把公鑰丟給我的時候,同時去CA申請一份數(shù)字證書,其實主要就是公鑰的消息摘要,有了這份證書,當我再用公鑰加密的時候,我就可以先驗證一下當前的公鑰是否確定是服務器A發(fā)送給我的。
這里就貼一種RSA的:

package com.amuro.strategy.signature;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RSASign
{
 public static boolean verifySign(String src)
 {
 try
 {
  KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
  keyPairGenerator.initialize(512);
  KeyPair keyPair = keyPairGenerator.generateKeyPair();
  PublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
  PrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();

  PKCS8EncodedKeySpec pkcs8EncodedKeySpec 
  = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
  Signature signature = Signature.getInstance("MD5withRSA");
  signature.initSign(privateKey);
  signature.update(src.getBytes());
  //生成簽名bytes
  byte[] signBytes = signature.sign();

  X509EncodedKeySpec x509EncodedKeySpec =
   new X509EncodedKeySpec(rsaPublicKey.getEncoded());
  keyFactory = KeyFactory.getInstance("RSA");
  PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
  signature = Signature.getInstance("MD5withRSA");
  signature.initVerify(publicKey);
  signature.update(src.getBytes());
  boolean isVerified = signature.verify(signBytes);

  return isVerified;
 }
 catch(Exception e)
 {
  e.printStackTrace();
 }

 return false;
 }

}

關(guān)于數(shù)字簽名和非對稱加密算法的使用,還看到一個非常棒的例子,分享給大家:
唉,這個月買了太多的書,到月底揭不開鍋了。正巧在QQ上遇到了Clark:
1-2-3:“Clark,我需要200兩紋銀,能否借給我?”
Clark:“沒問題。我這就給你轉(zhuǎn)賬。請給我一張借條?!?br /> 1-2-3:“太謝謝了,我這就用Word寫一個借條給你?!?br /> 然后,我新建一個Word文檔,寫好借條,存盤。然后,然后怎么辦呢?我不能直接把借條發(fā)送給Clark,原因有:
1. 我無法保證Clark不會在收到借條后將“紋銀200兩”改為“紋銀2000兩”。
2. 如果我賴賬,Clark無法證明這個借條就是我寫的。
3. 普通的Word文檔不能作為打官司的證據(jù)。
好在我早就申請了數(shù)字證書。我先用我的私鑰對借條進行加密,然后將加密后的密文用QQ發(fā)送給Clark。Clark收到了借條的密文后,在數(shù)字證書認證中心的網(wǎng)站上下載我的公鑰,然后使用我的公鑰將密文解密,發(fā)現(xiàn)確實寫的是“借紋銀200兩”,Clark就可以把銀子放心的借給我了,我也不會擔心Clark會篡改我的借條,原因是:
1. 由于我發(fā)給Clark的是密文,Clark無法進行修改。Clark倒是可以修改解密后的借條,但是Clark沒有我的私鑰,沒法模仿我對借條進行加密。這就叫防篡改。
2. 由于用我的私鑰進行加密的借條,有且只有我的公鑰可以解密。反過來講,能用我的公鑰解密的借條,一定是使用我的私鑰加密的,而只有我才擁有我的私鑰,這樣Clark就可以證明這個借條就是我寫的。這就叫防抵賴。
3. 如果我一直賴著不還錢,Clark把我告上了法庭,這個用我的私鑰加密過的Word文檔就可以當作程堂證供。因為我國已經(jīng)出臺了《中華人民共和國電子簽名法》,使數(shù)字簽名具有了法律效力。
您一定已經(jīng)注意到了,這個使用我的私鑰進行了加密的借條,具有了防篡改、防抵賴的特性,并且可以作為程堂證供,就跟我對這個借條進行了“簽名”的效果是一樣的。對了,“使用我的私鑰對借條進行加密”的過程就叫做數(shù)字簽名。

這是一篇總結(jié)類文章,把一些常用的Java加密技術(shù)和核心代碼寫在這邊,供給需要朋友參考。

相關(guān)文章

  • java 實現(xiàn)反射 json動態(tài)轉(zhuǎn)實體類--fastjson

    java 實現(xiàn)反射 json動態(tài)轉(zhuǎn)實體類--fastjson

    這篇文章主要介紹了java 實現(xiàn)反射 json動態(tài)轉(zhuǎn)實體類--fastjson,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • kotlin基礎教程之類和繼承

    kotlin基礎教程之類和繼承

    這篇文章主要介紹了kotlin基礎教程之類和繼承的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • 布隆過濾器面試如何快速判斷元素是否在集合里

    布隆過濾器面試如何快速判斷元素是否在集合里

    這篇文章主要為大家介紹了布隆過濾器面試中如何快速判斷元素是否在集合里的完美回復,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-03-03
  • Spring事務事件監(jiān)控的實現(xiàn)

    Spring事務事件監(jiān)控的實現(xiàn)

    這篇文章主要介紹了Spring事務事件監(jiān)控的實現(xiàn)。本文首先會使用實例進行講解Spring事務事件是如何使用的,然后會講解這種使用方式的實現(xiàn)原理。感興趣的小伙伴們可以參考一下
    2018-10-10
  • java后端PayPal支付實現(xiàn)教程

    java后端PayPal支付實現(xiàn)教程

    本文主要介紹了java后端PayPal支付實現(xiàn)教程,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • mybatis-plus saveOrUpdateBatch踩坑記錄

    mybatis-plus saveOrUpdateBatch踩坑記錄

    這篇文章主要介紹了mybatis-plus saveOrUpdateBatch踩坑記錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Spring Security 實現(xiàn)多種登錄方式(常規(guī)方式外的郵件、手機驗證碼登錄)

    Spring Security 實現(xiàn)多種登錄方式(常規(guī)方式外的郵件、手機驗證碼登錄)

    本文主要介紹了Spring Security 實現(xiàn)多種登錄方式(常規(guī)方式外的郵件、手機驗證碼登錄),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 如何使用CountDownLatch同步java多線程

    如何使用CountDownLatch同步java多線程

    這篇文章主要介紹了如何使用CountDownLatch同步java多線程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • SpringBoot集成本地緩存性能之王Caffeine示例詳解

    SpringBoot集成本地緩存性能之王Caffeine示例詳解

    這篇文章主要為大家介紹了SpringBoot集成本地緩存性能之王Caffeine的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Java中的Kafka消費者詳解

    Java中的Kafka消費者詳解

    這篇文章主要介紹了Java中的Kafka消費者詳解,Kafka是一個分布式流行消息系統(tǒng),通常用于大規(guī)模數(shù)據(jù)處理和實時數(shù)據(jù)流應用程序,它具有高吞吐量、可擴展性和容錯性的特點,需要的朋友可以參考下
    2023-09-09

最新評論