欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

總結(jié)一些Java常用的加密算法

 更新時間:2021年06月11日 16:37:05   作者:外星喵  
今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識,文章圍繞著Java加密算法展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下

一、加密算法分類

加密算法通常分為三類:

對稱加密

指加密和解密使用相同密鑰的加密算法。對稱加密算法的優(yōu)點在于加解密效率高且易于實現(xiàn)。

不可逆加密

不可逆加密算法的特征是加密過程不需要密鑰,并且經(jīng)過加密的數(shù)據(jù)無法被解密,只有同樣輸入的輸入數(shù)據(jù)經(jīng)過同樣的不可逆算法才能得到同樣的加密數(shù)據(jù)。

非對稱加密

指加密和解密使用不同密鑰的加密算法,也稱為公私鑰加密。

二、加密算法的應(yīng)用

1.數(shù)字簽名:進行身份認證和數(shù)據(jù)完整性驗證,主要用到了非對稱密鑰加密技術(shù)與數(shù)字摘要技術(shù)。

2.數(shù)字證書:主要用來確保數(shù)字簽名才是安全有效的,數(shù)字證書由獨立的證書發(fā)行機構(gòu)發(fā)布。數(shù)字證書各不相同,每種證書可提供不同級別的可信度,該證書內(nèi)包含用戶的個人信息和他的公鑰信息,同時還附有認證中心的簽名信息。

3.MD5:對用戶密碼進行加密并進行保存。

4.網(wǎng)絡(luò)數(shù)據(jù)加密:保障傳輸?shù)臄?shù)據(jù)安全,即使被截獲報文,在沒有密匙的情況下也無法得知報文真實內(nèi)容。

5.SSL協(xié)議:在握手階段使用的是非對稱加密,在傳輸階段使用的是對稱加密,也就是說在SSL上傳送的數(shù)據(jù)是使用對稱密鑰加密的。同時HTTPS也是由SSL+HTTP協(xié)議構(gòu)建的可進行加密傳輸、身份認證(確認客戶端連接的目標主機是否是真實正確的主機)的網(wǎng)絡(luò)協(xié)議。

三、對稱加密算法實現(xiàn)

  • 優(yōu)點:算法對消息雙方公開、計算量小、加密速度快、加密效率高。
  • 缺點:在數(shù)據(jù)傳送前,發(fā)送方和接收方必須商定好秘鑰,然后雙方保存好秘鑰。如果一方的秘鑰被泄露,那么加密信息就會被破解。

3.1 DES介紹

DES全稱為Data Encryption Standard,即數(shù)據(jù)加密標準,是一種使用密鑰加密的塊算法,1977年被美國聯(lián)邦政府的國家標準局確定為聯(lián)邦資料處理標準(FIPS),并授權(quán)在非密級政府通信中使用,隨后該算法在國際上廣泛流傳開來。不過現(xiàn)在已經(jīng)有點過時了。

Java代碼實現(xiàn):

import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.SecretKeyFactory;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;

/**
 * DES加密介紹 DES是一種對稱加密算法,所謂對稱加密算法即:加密和解密使用相同密鑰的算法。DES加密算法出自IBM的研究,
 * 后來被美國政府正式采用,之后開始廣泛流傳,但是近些年使用越來越少,因為DES使用56位密鑰,以現(xiàn)代計算能力,
 * 24小時內(nèi)即可被破解。雖然如此,在某些簡單應(yīng)用中,我們還是可以使用DES加密算法,本文簡單講解DES的JAVA實現(xiàn) 。
 * 注意:DES加密和解密過程中,密鑰長度都必須是8的倍數(shù)
 */
public class DesDemo {
	public DesDemo() {
	}

	// 測試
	public static void main(String args[]) {
		// 待加密內(nèi)容
		String str = "cryptology";
		// 密碼,長度要是8的倍數(shù)
		String password = "95880288";

		byte[] result;
		try {
			result = DesDemo.encrypt(str.getBytes(), password);
			System.out.println("加密后:" + result);
			byte[] decryResult = DesDemo.decrypt(result, password);
			System.out.println("解密后:" + new String(decryResult));
		} catch (UnsupportedEncodingException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

	// 直接將如上內(nèi)容解密

	/**
	 * 加密
	 * 
	 * @param datasource
	 *            byte[]
	 * @param password
	 *            String
	 * @return byte[]
	 */
	public static byte[] encrypt(byte[] datasource, String password) {
		try {
			SecureRandom random = new SecureRandom();
			DESKeySpec desKey = new DESKeySpec(password.getBytes());
			// 創(chuàng)建一個密匙工廠,然后用它把DESKeySpec轉(zhuǎn)換成
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
			SecretKey securekey = keyFactory.generateSecret(desKey);
			// Cipher對象實際完成加密操作
			Cipher cipher = Cipher.getInstance("DES");
			// 用密匙初始化Cipher對象,ENCRYPT_MODE用于將 Cipher 初始化為加密模式的常量
			cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
			// 現(xiàn)在,獲取數(shù)據(jù)并加密
			// 正式執(zhí)行加密操作
			return cipher.doFinal(datasource); // 按單部分操作加密或解密數(shù)據(jù),或者結(jié)束一個多部分操作
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 解密
	 * 
	 * @param src
	 *            byte[]
	 * @param password
	 *            String
	 * @return byte[]
	 * @throws Exception
	 */
	public static byte[] decrypt(byte[] src, String password) throws Exception {
		// DES算法要求有一個可信任的隨機數(shù)源
		SecureRandom random = new SecureRandom();
		// 創(chuàng)建一個DESKeySpec對象
		DESKeySpec desKey = new DESKeySpec(password.getBytes());
		// 創(chuàng)建一個密匙工廠
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 返回實現(xiàn)指定轉(zhuǎn)換的
																			// Cipher
																			// 對象
		// 將DESKeySpec對象轉(zhuǎn)換成SecretKey對象
		SecretKey securekey = keyFactory.generateSecret(desKey);
		// Cipher對象實際完成解密操作
		Cipher cipher = Cipher.getInstance("DES");
		// 用密匙初始化Cipher對象
		cipher.init(Cipher.DECRYPT_MODE, securekey, random);
		// 真正開始解密操作
		return cipher.doFinal(src);
	}
}

3.2 IDEA介紹

  •  這種算法是在DES算法的基礎(chǔ)上發(fā)展出來的,類似于三重DES。
  • 發(fā)展IDEA也是因為感到DES具有密鑰太短等缺點。
  • DEA的密鑰為128位,這么長的密鑰在今后若干年內(nèi)應(yīng)該是安全的。
  • 在實際項目中用到的很少了解即可。

 Java代碼實現(xiàn)

import java.security.Key;
import java.security.Security;

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

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class IDEADemo {
	public static void main(String args[]) {
		bcIDEA();
	}
	public static void bcIDEA() {
	    String src = "www.xttblog.com security idea";
	    try {
	        Security.addProvider(new BouncyCastleProvider());
	         
	        //生成key
	        KeyGenerator keyGenerator = KeyGenerator.getInstance("IDEA");
	        keyGenerator.init(128);
	        SecretKey secretKey = keyGenerator.generateKey();
	        byte[] keyBytes = secretKey.getEncoded();
	         
	        //轉(zhuǎn)換密鑰
	        Key key = new SecretKeySpec(keyBytes, "IDEA");
	         
	        //加密
	        Cipher cipher = Cipher.getInstance("IDEA/ECB/ISO10126Padding");
	        cipher.init(Cipher.ENCRYPT_MODE, key);
	        byte[] result = cipher.doFinal(src.getBytes());
	        System.out.println("bc idea encrypt : " + Base64.encodeBase64String(result));
	         
	        //解密
	        cipher.init(Cipher.DECRYPT_MODE, key);
	        result = cipher.doFinal(result);
	        System.out.println("bc idea decrypt : " + new String(result));
	    } catch (Exception e) {
	        e.printStackTrace();
	    }
	}
}

四、不可逆加密算法

  • 優(yōu)點:不可逆、易計算、特征化
  • 缺點:可能存在散列沖突

4.1 MD5介紹

MD5的作用是讓大容量信息在用數(shù)字簽名軟件簽署私人密鑰前被"壓縮"成一種保密的格式
(也就是把一個任意長度的字節(jié)串變換成一定長的十六進制數(shù)字串)。

主要有以下特點:

  • 1.壓縮性: 任意長度的數(shù)據(jù),算出的MD5值長度都是固定的。
  • 2.容易計算: 從原數(shù)據(jù)計算出MD5值很容易。
  • 3.抗修改性: 對原數(shù)據(jù)進行任何改動,哪怕只修改1個字節(jié),所得到的MD5值都有很大區(qū)別。
  • 4.強抗碰撞: 已知原數(shù)據(jù)和其MD5值,想找到一個具有相同MD5值的數(shù)據(jù)(即偽造數(shù)據(jù))是非常困難的。

Java代碼實現(xiàn)

import java.security.MessageDigest;

//利用JDK提供java.security.MessageDigest類實現(xiàn)MD5算法
public class MD5Demo {

    public static void main(String[] args) {
        System.out.println(getMD5Code("不可逆加密算法"));
    }

    private MD5Demo() {
    }

    // md5加密
    public static String getMD5Code(String message) {
        String md5Str = "";
        try {
        	//創(chuàng)建MD5算法消息摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            //生成的哈希值的字節(jié)數(shù)組
            byte[] md5Bytes = md.digest(message.getBytes());
            md5Str = bytes2Hex(md5Bytes);
        }catch(Exception e) {
            e.printStackTrace();
        }
        return md5Str;
    }

    // 2進制轉(zhuǎn)16進制
    public static String bytes2Hex(byte[] bytes) {
        StringBuffer result = new StringBuffer();
        int temp;
        try {
            for (int i = 0; i < bytes.length; i++) {
                temp = bytes[i];
                if(temp < 0) {
                    temp += 256;
                }
                if (temp < 16) {
                    result.append("0");
                }
                result.append(Integer.toHexString(temp));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }
}

4.2 SHA1介紹

對于長度小于2^64位的消息,SHA1會產(chǎn)生一個160位(40個字符)的消息摘要。當接收到消息的時候,這個消息摘要可以用來驗證數(shù)據(jù)的完整性。在傳輸?shù)倪^程中,數(shù)據(jù)很可能會發(fā)生變化,那么這時候就會產(chǎn)生不同的消息摘要。

SHA1有如下特性:

  • 不可以從消息摘要中復(fù)原信息;
  • 兩個不同的消息不會產(chǎn)生同樣的消息摘要,(但會有1x10 ^ 48分之一的機率出現(xiàn)相同的消息摘要,一般使用時忽略)。

 Java代碼實現(xiàn)

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SHA1Demo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(getSha1("不可逆加密算法"));
	
	}

	public static String getSha1(String str) {
		if (null == str || 0 == str.length()) {
			return null;
		}
		char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
		try {
			//創(chuàng)建SHA1算法消息摘要對象
			MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
			//使用指定的字節(jié)數(shù)組更新摘要。
			mdTemp.update(str.getBytes("UTF-8"));
			//生成的哈希值的字節(jié)數(shù)組
			byte[] md = mdTemp.digest();
			//SHA1算法生成信息摘要關(guān)鍵過程
			int j = md.length;
		    char[] buf = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = md[i];
				buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
				buf[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(buf);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return "0";
		
	}
}

4.3 HMAC 介紹

HMAC 是密鑰相關(guān)的 哈希運算消息認證碼(Hash-based Message Authentication Code),HMAC 運算利用 哈希算法 (MD5、SHA1 等),以 一個密鑰 和 一個消息 為輸入,生成一個 消息摘要 作為 輸出。

HMAC 發(fā)送方 和 接收方 都有的 key 進行計算,而沒有這把 key 的第三方,則是 無法計算 出正確的 散列值的,這樣就可以 防止數(shù)據(jù)被篡改。

Java代碼實現(xiàn)

import net.pocrd.annotation.NotThreadSafe;
import net.pocrd.define.ConstField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Arrays;


@NotThreadSafe
public class HMacHelper {
    private static final Logger logger = LoggerFactory.getLogger(HMacHelper.class);
    private Mac mac;

    /**
     * MAC算法可選以下多種算法
     * HmacMD5/HmacSHA1/HmacSHA256/HmacSHA384/HmacSHA512
     */
    private static final String KEY_MAC = "HmacMD5";
    public HMacHelper(String key) {
        try {
            SecretKey secretKey = new SecretKeySpec(key.getBytes(ConstField.UTF8), KEY_MAC);
            mac = Mac.getInstance(secretKey.getAlgorithm());
            mac.init(secretKey);
        } catch (Exception e) {
            logger.error("create hmac helper failed.", e);
        }
    }
    public byte[] sign(byte[] content) {
        return mac.doFinal(content);
    }

    public boolean verify(byte[] signature, byte[] content) {
        try {
            byte[] result = mac.doFinal(content);
            return Arrays.equals(signature, result);
        } catch (Exception e) {
            logger.error("verify sig failed.", e);
        }
        return false;
    }
}

五、非對稱加密

  • 優(yōu)點:非對稱加密與對稱加密相比其安全性更好,只要私鑰不泄露,很難被破解。
  • 缺點:加密和解密花費時間長、速度慢,只適合對少量數(shù)據(jù)進行加密。

5.1 RSA介紹

RSA是目前最有影響力和最常用的公鑰加密算法。它能夠抵抗到目前為止已知的絕大多數(shù)密碼攻擊,已被ISO推薦為公鑰數(shù)據(jù)加密標準。RSA公開密鑰密碼體制的原理是:根據(jù)數(shù)論,尋求兩個大素數(shù)比較簡單,而將它們的乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰

Java代碼實現(xiàn)

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

import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

/**
 * Created by humf.需要依賴 commons-codec 包
 */
public class RSADemo {

	public static void main(String[] args) throws Exception {
		Map<String, Key> keyMap = initKey();
		String publicKey = getPublicKey(keyMap);
		String privateKey = getPrivateKey(keyMap);

		System.out.println(keyMap);
		System.out.println("-----------------------------------");
		System.out.println(publicKey);
		System.out.println("-----------------------------------");
		System.out.println(privateKey);
		System.out.println("-----------------------------------");
		byte[] encryptByPrivateKey = encryptByPrivateKey("123456".getBytes(), privateKey);
		byte[] encryptByPublicKey = encryptByPublicKey("123456", publicKey);
		System.out.println(encryptByPrivateKey);
		System.out.println("-----------------------------------");
		System.out.println(encryptByPublicKey);
		System.out.println("-----------------------------------");
		String sign = sign(encryptByPrivateKey, privateKey);
		System.out.println(sign);
		System.out.println("-----------------------------------");
		boolean verify = verify(encryptByPrivateKey, publicKey, sign);
		System.out.println(verify);
		System.out.println("-----------------------------------");
		byte[] decryptByPublicKey = decryptByPublicKey(encryptByPrivateKey, publicKey);
		byte[] decryptByPrivateKey = decryptByPrivateKey(encryptByPublicKey, privateKey);
		System.out.println(decryptByPublicKey);
		System.out.println("-----------------------------------");
		System.out.println(decryptByPrivateKey);

	}

	public static final String KEY_ALGORITHM = "RSA";
	public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

	private static final String PUBLIC_KEY = "RSAPublicKey";
	private static final String PRIVATE_KEY = "RSAPrivateKey";

	public static byte[] decryptBASE64(String key) {
		return Base64.decodeBase64(key);
	}

	public static String encryptBASE64(byte[] bytes) {
		return Base64.encodeBase64String(bytes);
	}

	/**
	 * 用私鑰對信息生成數(shù)字簽名
	 *
	 * @param data
	 *            加密數(shù)據(jù)
	 * @param privateKey
	 *            私鑰
	 * @return
	 * @throws Exception
	 */
	public static String sign(byte[] data, String privateKey) throws Exception {
		// 解密由base64編碼的私鑰
		byte[] keyBytes = decryptBASE64(privateKey);
		// 構(gòu)造PKCS8EncodedKeySpec對象
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		// KEY_ALGORITHM 指定的加密算法
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		// 取私鑰匙對象
		PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
		// 用私鑰對信息生成數(shù)字簽名
		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
		signature.initSign(priKey);
		signature.update(data);
		return encryptBASE64(signature.sign());
	}

	/**
	 * 校驗數(shù)字簽名
	 *
	 * @param data
	 *            加密數(shù)據(jù)
	 * @param publicKey
	 *            公鑰
	 * @param sign
	 *            數(shù)字簽名
	 * @return 校驗成功返回true 失敗返回false
	 * @throws Exception
	 */
	public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
		// 解密由base64編碼的公鑰
		byte[] keyBytes = decryptBASE64(publicKey);
		// 構(gòu)造X509EncodedKeySpec對象
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
		// KEY_ALGORITHM 指定的加密算法
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		// 取公鑰匙對象
		PublicKey pubKey = keyFactory.generatePublic(keySpec);
		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
		signature.initVerify(pubKey);
		signature.update(data);
		// 驗證簽名是否正常
		return signature.verify(decryptBASE64(sign));
	}

	public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
		// 對密鑰解密
		byte[] keyBytes = decryptBASE64(key);
		// 取得私鑰
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
		// 對數(shù)據(jù)解密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		return cipher.doFinal(data);
	}

	/**
	 * 解密<br>
	 * 用私鑰解密
	 *
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] decryptByPrivateKey(String data, String key) throws Exception {
		return decryptByPrivateKey(decryptBASE64(data), key);
	}

	/**
	 * 解密<br>
	 * 用公鑰解密
	 *
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
		// 對密鑰解密
		byte[] keyBytes = decryptBASE64(key);
		// 取得公鑰
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key publicKey = keyFactory.generatePublic(x509KeySpec);
		// 對數(shù)據(jù)解密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, publicKey);
		return cipher.doFinal(data);
	}

	/**
	 * 加密<br>
	 * 用公鑰加密
	 *
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptByPublicKey(String data, String key) throws Exception {
		// 對公鑰解密
		byte[] keyBytes = decryptBASE64(key);
		// 取得公鑰
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key publicKey = keyFactory.generatePublic(x509KeySpec);
		// 對數(shù)據(jù)加密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
		return cipher.doFinal(data.getBytes());
	}

	/**
	 * 加密<br>
	 * 用私鑰加密
	 *
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {
		// 對密鑰解密
		byte[] keyBytes = decryptBASE64(key);
		// 取得私鑰
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
		// 對數(shù)據(jù)加密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, privateKey);
		return cipher.doFinal(data);
	}

	/**
	 * 取得私鑰
	 *
	 * @param keyMap
	 * @return
	 * @throws Exception
	 */
	public static String getPrivateKey(Map<String, Key> keyMap) throws Exception {
		Key key = (Key) keyMap.get(PRIVATE_KEY);
		return encryptBASE64(key.getEncoded());
	}

	/**
	 * 取得公鑰
	 *
	 * @param keyMap
	 * @return
	 * @throws Exception
	 */
	public static String getPublicKey(Map<String, Key> keyMap) throws Exception {
		Key key = keyMap.get(PUBLIC_KEY);
		return encryptBASE64(key.getEncoded());
	}

	/**
	 * 初始化密鑰
	 *
	 * @return
	 * @throws Exception
	 */
	public static Map<String, Key> initKey() throws Exception {
		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
		keyPairGen.initialize(1024);
		KeyPair keyPair = keyPairGen.generateKeyPair();
		Map<String, Key> keyMap = new HashMap(2);
		keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公鑰
		keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// 私鑰
		return keyMap;
	}

}

5.2 ECC 介紹

ECC 也是一種 非對稱加密算法,主要優(yōu)勢是在某些情況下,它比其他的方法使用 更小的密鑰,比如 RSA 加密算法,提供 相當?shù)幕蚋叩燃?/strong> 的安全級別。不過一個缺點是 加密和解密操作 的實現(xiàn)比其他機制 時間長 (相比 RSA 算法,該算法對 CPU 消耗嚴重)。

Java代碼實現(xiàn)

import net.pocrd.annotation.NotThreadSafe;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.Security;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

@NotThreadSafe
public class EccHelper {
    private static final Logger logger = LoggerFactory.getLogger(EccHelper.class);
    private static final int SIZE = 4096;
    private BCECPublicKey  publicKey;
    private BCECPrivateKey privateKey;

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public EccHelper(String publicKey, String privateKey) {
        this(Base64Util.decode(publicKey), Base64Util.decode(privateKey));
    }

    public EccHelper(byte[] publicKey, byte[] privateKey) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
            if (publicKey != null && publicKey.length > 0) {
                this.publicKey = (BCECPublicKey)keyFactory.generatePublic(new X509EncodedKeySpec(publicKey));
            }
            if (privateKey != null && privateKey.length > 0) {
                this.privateKey = (BCECPrivateKey)keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKey));
            }
        } catch (ClassCastException e) {
            throw new RuntimeException("", e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public EccHelper(String publicKey) {
        this(Base64Util.decode(publicKey));
    }

    public EccHelper(byte[] publicKey) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
            if (publicKey != null && publicKey.length > 0) {
                this.publicKey = (BCECPublicKey)keyFactory.generatePublic(new X509EncodedKeySpec(publicKey));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public byte[] encrypt(byte[] content) {
        if (publicKey == null) {
            throw new RuntimeException("public key is null.");
        }
        try {
            Cipher cipher = Cipher.getInstance("ECIES", "BC");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            int size = SIZE;
            ByteArrayOutputStream baos = new ByteArrayOutputStream((content.length + size - 1) / size * (size + 45));
            int left = 0;
            for (int i = 0; i < content.length; ) {
                left = content.length - i;
                if (left > size) {
                    cipher.update(content, i, size);
                    i += size;
                } else {
                    cipher.update(content, i, left);
                    i += left;
                }
                baos.write(cipher.doFinal());
            }
            return baos.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public byte[] decrypt(byte[] secret) {
        if (privateKey == null) {
            throw new RuntimeException("private key is null.");
        }
        try {
            Cipher cipher = Cipher.getInstance("ECIES", "BC");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            int size = SIZE + 45;
            ByteArrayOutputStream baos = new ByteArrayOutputStream((secret.length + size + 44) / (size + 45) * size);
            int left = 0;
            for (int i = 0; i < secret.length; ) {
                left = secret.length - i;
                if (left > size) {
                    cipher.update(secret, i, size);
                    i += size;
                } else {
                    cipher.update(secret, i, left);
                    i += left;
                }
                baos.write(cipher.doFinal());
            }
            return baos.toByteArray();
        } catch (Exception e) {
            logger.error("ecc decrypt failed.", e);
        }
        return null;
    }

    public byte[] sign(byte[] content) {
        if (privateKey == null) {
            throw new RuntimeException("private key is null.");
        }
        try {
            Signature signature = Signature.getInstance("SHA1withECDSA", "BC");
            signature.initSign(privateKey);
            signature.update(content);
            return signature.sign();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public boolean verify(byte[] sign, byte[] content) {
        if (publicKey == null) {
            throw new RuntimeException("public key is null.");
        }
        try {
            Signature signature = Signature.getInstance("SHA1withECDSA", "BC");
            signature.initVerify(publicKey);
            signature.update(content);
            return signature.verify(sign);
        } catch (Exception e) {
            logger.error("ecc verify failed.", e);
        }
        return false;
    }
}

到此這篇關(guān)于總結(jié)一些Java常用的加密算法的文章就介紹到這了,更多相關(guān)Java加密算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 生成隨機單據(jù)號的實現(xiàn)示例

    Java 生成隨機單據(jù)號的實現(xiàn)示例

    本文主要介紹了Java 生成隨機單據(jù)號的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-09-09
  • Java注解機制之Spring自動裝配實現(xiàn)原理詳解

    Java注解機制之Spring自動裝配實現(xiàn)原理詳解

    這篇文章主要為大家詳細介紹了Java注解機制之Spring自動裝配實現(xiàn)原理,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • SSH框架網(wǎng)上商城項目第11戰(zhàn)之查詢和刪除商品功能實現(xiàn)

    SSH框架網(wǎng)上商城項目第11戰(zhàn)之查詢和刪除商品功能實現(xiàn)

    這篇文章主要為大家詳細介紹了SSH框架網(wǎng)上商城項目第11戰(zhàn)之查詢和刪除商品功能實現(xiàn)的相關(guān)資料,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-06-06
  • Struts2的配置文件方法小結(jié)

    Struts2的配置文件方法小結(jié)

    最近正在學習Struts2,在配置文件中遇到好多標簽,各種意義不同。下面這篇文章就來給大家介紹關(guān)于Struts2配置文件的相關(guān)資料,文中通過圖文介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧。
    2018-04-04
  • Java實現(xiàn)對視頻進行截圖的方法【附ffmpeg下載】

    Java實現(xiàn)對視頻進行截圖的方法【附ffmpeg下載】

    這篇文章主要介紹了Java實現(xiàn)對視頻進行截圖的方法,結(jié)合實例形式分析了Java使用ffmpeg針對視頻進行截圖的相關(guān)操作技巧,并附帶ffmpeg.exe文件供讀者下載使用,需要的朋友可以參考下
    2018-01-01
  • MyBatisPlus-QueryWrapper多條件查詢及修改方式

    MyBatisPlus-QueryWrapper多條件查詢及修改方式

    這篇文章主要介紹了MyBatisPlus-QueryWrapper多條件查詢及修改方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 詳解Spring與Mybatis整合方法(基于IDEA中的Maven整合)

    詳解Spring與Mybatis整合方法(基于IDEA中的Maven整合)

    這篇文章主要介紹了Spring與Mybatis整合方法(基于IDEA中的Maven整合),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • Spring @Import注解的使用

    Spring @Import注解的使用

    @Import注解算是SpringBoot自動配置原理中一個很重要的注解,本文介紹了該注解的源碼分析及使用方法,感興趣的朋友可以了解下
    2021-05-05
  • 解決Mybatis中result標簽識別不了的情況

    解決Mybatis中result標簽識別不了的情況

    這篇文章主要介紹了解決Mybatis中result標簽識別不了的情況,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教。
    2022-01-01
  • Java中的關(guān)鍵字_動力節(jié)點Java學院整理

    Java中的關(guān)鍵字_動力節(jié)點Java學院整理

    關(guān)鍵字也稱為保留字,是指Java語言中規(guī)定了特定含義的標示符。對于保留字,用戶只能按照系統(tǒng)規(guī)定的方式使用,不能自行定義
    2017-04-04

最新評論