程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 總結Java經常使用到的六個加密技巧和代碼

總結Java經常使用到的六個加密技巧和代碼

編輯:關於JAVA

總結Java經常使用到的六個加密技巧和代碼。本站提示廣大學習愛好者:(總結Java經常使用到的六個加密技巧和代碼)文章只能為提供參考,不一定能成為您想要的結果。以下是總結Java經常使用到的六個加密技巧和代碼正文


加密,是以某種特別的算法轉變原本的信息數據,使得未受權的用戶即便取得了已加密的信息,但因不知解密的辦法,依然沒法懂得信息的內容。年夜體上分為雙向加密和單向加密,而雙向加密又分為對稱加密和非對稱加密(有些材料將加密直接分為對稱加密和非對稱加密)。

雙向加密年夜體意思就是明文加密後構成密文,可以經由過程算法復原成明文。而單向加密只是對信息停止了摘要盤算,不克不及經由過程算法生成明文,單向加密從嚴厲意思上說不克不及算是加密的一種,應當算是摘要算法吧。

詳細來講:
體系必需可用,非數學上弗成譯碼。
體系紛歧定要保密,可以隨意馬虎落入仇敵手中。
密匙必需可以不經籍寫的材料交流和記憶,且兩邊可以轉變密匙。
體系可以用於電訊。
體系可以轉移地位,它的功效必需不消經由幾小我之手才可到達。
體系輕易應用,不請求應用者的腦力過份勞累或有許多的規矩。

1、重要的加密方法代碼供給方
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就夠了。

2、Base64算法
1、從如今加密算法的龐雜性來看Base64這類都欠好意思說本身是加密,不外關於完整不懂盤算機的人來講也夠用了。采取Base64編碼具有弗成讀性,即所編碼的數據不會被人用肉眼所直接看到。
Base64編碼普通用於url的處置,或許說任何你不想讓通俗人一眼就曉得是啥的器械都可以用Base64編碼處置後再宣布在收集上。

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編碼對應關系表

3、新聞摘要算法(Message Digest)
新聞摘要(Message Digest)又稱為數字摘要(Digital Digest)。它是一個獨一對應一個新聞或文本的固定長度的值,它由一個單向Hash加密函數抵消息停止感化而發生。HASH函數的抗抵觸性使得假如一段明文稍有變更,哪怕只更改該段落的一個字母,經由過程哈希算法感化後都將發生分歧的值。而HASH算法的單向性使得要找到哈希值雷同的兩個分歧的輸出新聞,在盤算上是弗成能的。所以數據的哈希值,即新聞摘要,可以磨練數據的完全性。
用年夜白話來講,任何一段數據應當都和人一樣是獨一的,獨一的標識是甚麼,人類的話今朝就是指紋,而數據的指紋是甚麼呢?沒錯,就是新聞摘要算法發生的這一段String。好比我們在注冊網站的時刻,客戶端向辦事器傳輸的,應當是我們輸出的暗碼停止新聞摘要處置後的內容,如許就算辦事器被攻破,Hack也沒法曉得用戶真實的暗碼是甚麼。不外有說如今MD5和SHA曾經被攻破了,詳細年夜家可以谷歌。
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");
 }

}

4、對稱加密
采取單鑰暗碼體系的加密辦法,統一個密鑰可以同時用作信息的加密息爭密,這類加密辦法稱為對稱加密,也稱為單密鑰加密。而由於加密息爭密都應用統一個密鑰,若何把密鑰平安地傳遞到解密者手上就成了必需要處理的成績。固然,平安性較低帶來的長處就是優盤算量小、加密速度快、加密效力高。
然並卵,古代盤算機對這類級其余盤算量早就不care了,平安才是最主要的。
1、DES
DES,全稱為“Data Encryption Standard”,中文名為“數據加密尺度”,是一種應用密鑰加密的塊算法。DES 算法為暗碼體系體例中的對稱暗碼體系體例,又被稱為美國數據加密尺度,是 1972 年美國 IBM 公司研制的對稱暗碼體系體例加密算法。 明文按 64 位停止分組,密鑰長 64 位,密鑰現實上是 56 位介入 DES 運算(第8、16、24、32、40、48、56、64 位是校驗位, 使得每一個密鑰都有奇數個 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”,中文名“三重數據加密算法”,它相當因而對每一個數據塊運用三次 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 加密法,是美國聯邦當局采取的一種區塊加密尺度。AES 加密算法作為新一代的數據加密尺度會聚了強平安性、高機能、高效力、易用和靈巧等長處。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”,中文名“基於口令加密”,是一種基於暗碼的加密算法,其特色是應用口令取代了密鑰,而口令由用戶本身掌管,采取隨機數雜湊多重加密等辦法包管數據的平安性。
PBE算法沒有密鑰的概念,把口令當作密鑰了。由於密鑰長短影響算法平安性,還不便利記憶,這裡我們直接換成我們本身經常使用的口令就年夜年夜分歧了,便於我們的記憶。然則純真的口令很輕易被字典法給窮舉出來,所以我們這裡給口令加了點“鹽”,這個鹽和口令組合,想破解就難了。同時我們將鹽和口令歸並後用新聞摘要算法停止迭代許多次來構建密鑰初始化向量的根本資料,使破譯加倍難了。

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;
 }

}

5、非對稱加密
非對稱加密算法須要兩個密鑰來停止加密息爭密,分離是公鑰和私鑰。須要留意的一點,這個公鑰和私鑰必需是一對的,假如用公鑰對數據停止加密,那末只要應用對應的私鑰能力解密,反之亦然。因為加密息爭密應用的是兩個分歧的密鑰,是以,這類算法叫做非對稱加密算法。
1、RSA
其實,在早在 1978 年的時刻,RSA就曾經湧現了,它是第一個既能用於數據加密也能用於數字簽名的算法。它易於懂得和操作,也很風行。其道理就如下面的任務進程所述。RSA 算法基於一個非常簡略的數論現實:將兩個年夜素數相乘非常輕易,然則想要對其乘積停止因式分化卻極端艱苦,是以可以將乘積地下作為加密密鑰。

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平安穿越不平安收集的辦法,也就是常說的密鑰分歧協定。由地下密鑰暗碼體系體例的奠定人Diffie和Hellman所提出的一種思惟。簡略的說就是許可兩名用戶在地下媒體上交流信息以生成“分歧”的、可以同享的密鑰。也就是由甲方產出一對密鑰(公鑰、私鑰),乙方按照甲方公鑰發生乙方密鑰對(公鑰、私鑰)。
以此為基線,作為數據傳輸保密基本,同時兩邊應用統一種對稱加密算法構建當地密鑰(SecretKey)對數據加密。如許,在互通了當地密鑰(SecretKey)算法後,甲乙兩邊地下本身的公鑰,應用對方的公鑰和適才發生的私鑰加密數據,同時可使用對方的公鑰和本身的私鑰對數據解密。不單單是甲乙兩邊兩方,可以擴大為多方同享數據通信,如許就完成了收集交互數據的平安通信!

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
 {
  //初始化發送方密鑰
  KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");
  senderKeyPairGenerator.initialize(512);
  KeyPair senderkeyPair = senderKeyPairGenerator.generateKeyPair();
  PrivateKey senderPrivateKey = senderkeyPair.getPrivate();
  byte[] senderPublicKeyBytes = senderkeyPair.getPublic().getEncoded();//發送方的公鑰

  //初始化吸收方密鑰,用發送方的公鑰
  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");

  //發送方拿到吸收方的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;
 }

}

6、數字簽名證書
非對稱加密曾經灰常平安了,然則還有一個馬腳:
辦事器A頒布了本身的公鑰,我的電腦是用辦事器A的公鑰加密數據後再發給辦事器A的;這時候候辦事器B侵入了我的電腦,把我用來加密的公鑰換成了它的公鑰,因而我收回去的數據就會被辦事器B的私鑰破解了。腫麼避免公鑰被改動呢?
對,我們想到了後面的新聞摘要,辦事器A把公鑰丟給我的時刻,同時去CA請求一份數字證書,其實重要就是公鑰的新聞摘要,有了這份證書,當我再用公鑰加密的時刻,我便可以先驗證一下以後的公鑰能否肯定是辦事器A發送給我的。
這裡就貼一種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;
 }

}

關於數字簽名和非對稱加密算法的應用,還看到一個異常棒的例子,分享給年夜家:
唉,這個月買了太多的書,到月底揭不開鍋了。正巧在QQ上碰到了Clark:
1-2-3:“Clark,我須要200兩紋銀,可否借給我?”
Clark:“沒成績。我這就給你轉賬。請給我一張借單。”
1-2-3:“太感謝了,我這就用Word寫一個借單給你。”
然後,我新建一個Word文檔,寫好借單,存盤。然後,然後怎樣辦呢?我不克不及直接把借單發送給Clark,緣由有:
1. 我沒法包管Clark不會在收到借單後將“紋銀200兩”改成“紋銀2000兩”。
2. 假如我認賬,Clark沒法證實這個借單就是我寫的。
3. 通俗的Word文檔不克不及作為打訟事的證據。
好在我早就請求了數字證書。我先用我的私鑰對借單停止加密,然後將加密後的密文用QQ發送給Clark。Clark收到了借單的密文後,在數字證書認證中間的網站高低載我的公鑰,然後應用我的公鑰將密文解密,發明確切寫的是“借紋銀200兩”,Clark便可以把銀子寧神的借給我了,我也不會擔憂Clark會改動我的借單,緣由是:
1. 因為我發給Clark的是密文,Clark沒法停止修正。Clark卻是可以修正解密後的借單,然則Clark沒有我的私鑰,沒法模擬我對借單停止加密。這就叫防改動。
2. 因為用我的私鑰停止加密的借單,有且只要我的公鑰可以解密。反過去講,能用我的公鑰解密的借單,必定是應用我的私鑰加密的,而只要我才具有我的私鑰,如許Clark便可以證實這個借單就是我寫的。這就叫防狡賴。
3. 假如我一向賴著不還錢,Clark把我告上了法庭,這個用我的私鑰加密過的Word文檔便可以看成程堂證供。由於我國曾經出台了《中華國民共和國電子簽名法》,使數字簽名具有了司法效率。
您必定曾經留意到了,這個應用我的私鑰停止了加密的借單,具有了防改動、防狡賴的特征,而且可以作為程堂證供,就跟我對這個借單停止了“簽名”的後果是一樣的。對了,“應用我的私鑰對借單停止加密”的進程就叫做數字簽名。

這是一篇總結類文章,把一些經常使用的Java加密技巧和焦點代碼寫在這邊,供應須要同伙參考。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved