【JAVA】常用加解密演算法總結及JAVA實現【BASE64,MD5,SHA,DES,3DES,AES,RSA】
BASE64
這其實是一種編解碼方法,但是隻要我們能夠將原文變成肉眼不可識別的內容,其實就是一種加密的方法。
BASE64 的編碼都是按字串長度,以每 3 個 8 bit 的字元為一組,然後針對每組,首先獲取每個字元的 ASCII 編碼,然後將 ASCII 編碼轉換成 8 bit 的二進位制,得到一組 3*8=24 bit 的位元組。然後再將這 24 bit 劃分為 4 個 6 bit 的位元組,並在每個 6 bit 的位元組前面都填兩個高位 0,得到 4 個 8 bit 的位元組,然後將這 4 個 8 bit 的位元組轉換成十進位制,對照 BASE64 編碼表 ,得到對應編碼後的字元。
實現:
/** * Project Name:thread * File Name:Base64Util.java * Package Name:enc.dec * Date:2015年10月21日下午3:49:21 * Copyright (c) 2015, [email protected] All Rights Reserved. * */ package enc.dec; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; /** * ClassName:Base64Util <br/> * Function: TODO ADD FUNCTION. <br/> * Reason: TODO ADD REASON. <br/> * Date: 2015年10月21日 下午3:49:21 <br/> * * @author chiwei * @version * @since JDK 1.6 * @see */ public class Base64Util { private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" .toCharArray(); /** * data[]進行編碼 * * @param data * @return */ public static String encode(byte[] data) { int start = 0; int len = data.length; StringBuffer buf = new StringBuffer(data.length * 3 / 2); int end = len - 3; int i = start; int n = 0; while (i <= end) { int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 0x0ff) << 8) | (((int) data[i + 2]) & 0x0ff); buf.append(legalChars[(d >> 18) & 63]); buf.append(legalChars[(d >> 12) & 63]); buf.append(legalChars[(d >> 6) & 63]); buf.append(legalChars[d & 63]); i += 3; if (n++ >= 14) { n = 0; buf.append(" "); } } if (i == start + len - 2) { int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 255) << 8); buf.append(legalChars[(d >> 18) & 63]); buf.append(legalChars[(d >> 12) & 63]); buf.append(legalChars[(d >> 6) & 63]); buf.append("="); } else if (i == start + len - 1) { int d = (((int) data[i]) & 0x0ff) << 16; buf.append(legalChars[(d >> 18) & 63]); buf.append(legalChars[(d >> 12) & 63]); buf.append("=="); } return buf.toString(); } public static String encode(String data) { try { return encode(data.getBytes("UTF-8")); } catch (Exception e) { throw new RuntimeException(e); } } private static int decode(char c) { if (c >= 'A' && c <= 'Z') return ((int) c) - 65; else if (c >= 'a' && c <= 'z') return ((int) c) - 97 + 26; else if (c >= '0' && c <= '9') return ((int) c) - 48 + 26 + 26; else switch (c) { case '+': return 62; case '/': return 63; case '=': return 0; default: throw new RuntimeException("unexpected code: " + c); } } /** * Decodes the given Base64 encoded String to a new byte array. The byte * array holding the decoded data is returned. */ public static byte[] decode(String s) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { decode(s, bos); } catch (IOException e) { throw new RuntimeException(); } byte[] decodedBytes = bos.toByteArray(); try { bos.close(); bos = null; } catch (IOException ex) { throw new RuntimeException(ex); } return decodedBytes; } private static void decode(String s, OutputStream os) throws IOException { int i = 0; int len = s.length(); while (true) { while (i < len && s.charAt(i) <= ' ') i++; if (i == len) break; int tri = (decode(s.charAt(i)) << 18) + (decode(s.charAt(i + 1)) << 12) + (decode(s.charAt(i + 2)) << 6) + (decode(s.charAt(i + 3))); os.write((tri >> 16) & 255); if (s.charAt(i + 2) == '=') break; os.write((tri >> 8) & 255); if (s.charAt(i + 3) == '=') break; os.write(tri & 255); i += 4; } } /** * data[]進行編碼 * * @param data * @return */ public static String Base64Encoder(byte[] data) { int start = 0; int len = data.length; StringBuffer buf = new StringBuffer(data.length * 3 / 2); int end = len - 3; int i = start; int n = 0; while (i <= end) { int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 0x0ff) << 8) | (((int) data[i + 2]) & 0x0ff); buf.append(legalChars[(d >> 18) & 63]); buf.append(legalChars[(d >> 12) & 63]); buf.append(legalChars[(d >> 6) & 63]); buf.append(legalChars[d & 63]); i += 3; if (n++ >= 14) { // 不需要空格 n = 0; } } if (i == start + len - 2) { int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 255) << 8); buf.append(legalChars[(d >> 18) & 63]); buf.append(legalChars[(d >> 12) & 63]); buf.append(legalChars[(d >> 6) & 63]); buf.append("="); } else if (i == start + len - 1) { int d = (((int) data[i]) & 0x0ff) << 16; buf.append(legalChars[(d >> 18) & 63]); buf.append(legalChars[(d >> 12) & 63]); buf.append("=="); } return buf.toString(); } public static void main(String[] args) { System.out.println(encode("tree")); System.out.println(new String(decode(encode("tree")))); } }
加解密
MD5
Message Digest Algorithm 5
MD5 是用來驗證檔案的一致性的
/** * Project Name:thread * File Name:MD5Util.java * Package Name:enc.dec * Date:2015年10月21日下午3:58:02 * Copyright (c) 2015, [email protected] All Rights Reserved. * */ package enc.dec; import java.security.MessageDigest; /** * ClassName:MD5Util <br/> * Function: TODO ADD FUNCTION. <br/> * Reason: TODO ADD REASON. <br/> * Date: 2015年10月21日 下午3:58:02 <br/> * * @author chiwei * @version * @since JDK 1.6 * @see */ public class MD5Util { public static String getMD5(String source) { String s = null; char hexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(source.getBytes());// 使用指定的byte陣列更新摘要 byte[] hashCalc = md.digest();// 完成雜湊計算 char result[] = new char[16 * 2];// MD5結果返回的是32位字串,每位是16進製表示的 int k = 0; for (int i = 0; i < 16; i++) {// 迴圈16次,對每個位元組進行操作轉換 byte everyByte = hashCalc[i]; result[k++] = hexChar[everyByte >>> 4 & 0xf];// 對每個位元組的高4位進行處理,邏輯右移,再相與 result[k++] = hexChar[everyByte & 0xf];// 低4位轉換 } s = new String(result); } catch (Exception e) { throw new RuntimeException(e); } return s; } public static void main(String[] args) { System.out.println(getMD5("tree")); } }
SHA
Secure Hash Algorithm
SHA1
SHA-1 有兩個特點:
不可以從訊息摘要中復原資訊
兩個不同的訊息,不會產生同樣的訊息摘要
SHA-1 是一種資料加密演算法,主要是接收一段明文,然後以一種不可逆的方式將它轉換成一段密文,也可以簡單的理解為取一串輸入碼,並把它們轉化為長度較短、位數固定的輸出序列即雜湊值的過程。
對應的還有SHA-256,SHA-512,演算法更加安全
/**
* Project Name:thread
* File Name:SHAUtil.java
* Package Name:enc.dec
* Date:2015年10月21日下午4:01:50
* Copyright (c) 2015, [email protected] All Rights Reserved.
*
*/
package enc.dec;
import java.security.MessageDigest;
/**
* ClassName:SHAUtil <br/>
* Function: TODO ADD FUNCTION. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2015年10月21日 下午4:01:50 <br/>
*
* @author chiwei
* @version
* @since JDK 1.6
* @see
*/
public class SHAUtil {
/** 演算法種類 */
private final static String KEY_SHA1 = "SHA-1";
private final static String KEY_SHA256 = "SHA-256";
private final static String KEY_SHA512 = "SHA-512";
public static String encBySha1(String data) throws Exception {
// 建立具有指定演算法名稱的資訊摘要
MessageDigest sha = MessageDigest.getInstance(KEY_SHA1);
// 使用指定的位元組陣列對摘要進行最後更新
sha.update(data.getBytes());
// 完成摘要計算
byte[] bytes = sha.digest();
// 將得到的位元組陣列變成字串返回
return ByteUtil.byteArrayToHexString(bytes);
}
public static String encBySha256(String data) throws Exception {
// 建立具有指定演算法名稱的資訊摘要
MessageDigest sha = MessageDigest.getInstance(KEY_SHA256);
// 使用指定的位元組陣列對摘要進行最後更新
sha.update(data.getBytes());
// 完成摘要計算
byte[] bytes = sha.digest();
// 將得到的位元組陣列變成字串返回
return ByteUtil.byteArrayToHexString(bytes);
}
public static String encBySha512(String data) throws Exception {
// 建立具有指定演算法名稱的資訊摘要
MessageDigest sha = MessageDigest.getInstance(KEY_SHA512);
// 使用指定的位元組陣列對摘要進行最後更新
sha.update(data.getBytes());
// 完成摘要計算
byte[] bytes = sha.digest();
// 將得到的位元組陣列變成字串返回
return ByteUtil.byteArrayToHexString(bytes);
}
public static void main(String[] args) throws Exception {
String key = "123";
System.out.println(encBySha1(key));
System.out.println(encBySha256(key));
System.out.println(encBySha512(key));
}
}
DES,3DES,AES對稱加密
DES 演算法把 64 位的明文輸入塊變為 64 位的密文輸出塊,它所使用的金鑰也是 64 位,其演算法主要分為兩步:
初始置換
其功能是把輸入的 64 位資料塊按位重新組合,並把輸出分為 L0、R0 兩部分,每部分各長 32 位,其置換規則為將輸入的第 58 位換到第一位,第 50 位換到第 2 位 …… 依此類推,最後一位是原來的第 7 位。L0、R0 則是換位輸出後的兩部分,L0 是輸出的左 32 位,R0 是右 32 位,例:設定換前的輸入值為 D1 D2 D3 …… D64,則經過初始置換後的結果為:L0 = D58 D50 …… D8;R0 = D57 D49 …… D7。
逆置換
經過 16 次迭代運算後,得到 L16、R16,將此作為輸入,進行逆置換,逆置換正好是初始置換的逆運算,由此即得到密文輸出。
3DES,也就是“Triple DES”,中文名“三重資料加密演算法”,它相當於是對每個資料塊應用三次 DES 加密演算法。由於計算機運算能力的增強,原版 DES 密碼的金鑰長度變得容易被暴力破解;3DES 即是設計用來提供一種相對簡單的方法,即通過增加 DES 的金鑰長度來避免類似的攻擊,而不是設計一種全新的塊密碼演算法。
AES,全稱為“Advanced Encryption Standard”,中文名“高階加密標準”,在密碼學中又稱 Rijndael 加密法,是美國聯邦政府採用的一種區塊加密標準。AES 加密演算法作為新一代的資料加密標準匯聚了強安全性、高效能、高效率、易用和靈活等優點。AES 設計有三個金鑰長度:128,192,256 位。相對而言,AES 的 128 金鑰比 DES 的 56 金鑰強了 1021 倍。
/**
* Project Name:thread
* File Name:DESUtil.java
* Package Name:enc.dec
* Date:2015年10月21日下午4:17:14
* Copyright (c) 2015, [email protected] All Rights Reserved.
*
*/
package enc.dec;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
/**
* ClassName:DESUtil <br/>
* Function: TODO ADD FUNCTION. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2015年10月21日 下午4:17:14 <br/>
*
* @author chiwei
* @version
* @since JDK 1.6
* @see
*/
public class DESUtil {
private final static String KEY_DES = "DES";
private static final String KEY_3_DES = "DESede";
private final static String KEY_AES = "AES"; // 測試
//長度8位元組
private final static String DES_KEY = "12345678";
//長度24位元組
private final static String DES_3_KEY = "213456781234567812345678";
//長度16,24,32位元組
private final static String AES_KEY = "1234567812345678";
private static byte[] decByDes(byte[] data) throws Exception {
// DES演算法要求有一個可信任的隨機數源
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(DES_KEY.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_DES);
SecretKey securekey = keyFactory.generateSecret(desKey);
Cipher cipher = Cipher.getInstance(KEY_DES);
cipher.init(Cipher.DECRYPT_MODE, securekey, random);
return cipher.doFinal(data);
}
private static byte[] encByDes(byte[] data) throws Exception {
DESKeySpec desKey = new DESKeySpec(DES_KEY.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_DES);
SecretKey securekey = keyFactory.generateSecret(desKey);
Cipher cipher = Cipher.getInstance(KEY_DES);
cipher.init(Cipher.ENCRYPT_MODE, securekey);
return cipher.doFinal(data);
}
private static byte[] decBy3Des(byte[] data) throws Exception {
SecureRandom random = new SecureRandom();
SecretKey deskey = new SecretKeySpec(DES_3_KEY.getBytes(), KEY_3_DES);
Cipher cipher = Cipher.getInstance(KEY_3_DES);
cipher.init(Cipher.DECRYPT_MODE, deskey, random);
return cipher.doFinal(data);
}
private static byte[] encBy3Des(byte[] data) throws Exception {
SecureRandom random = new SecureRandom();
SecretKey deskey = new SecretKeySpec(DES_3_KEY.getBytes(), KEY_3_DES);
Cipher cipher = Cipher.getInstance(KEY_3_DES);
cipher.init(Cipher.ENCRYPT_MODE, deskey, random);
return cipher.doFinal(data);
}
private static byte[] decByAes(byte[] data) throws Exception {
SecretKey deskey = new SecretKeySpec(AES_KEY.getBytes(), KEY_AES);
Cipher cipher = Cipher.getInstance(KEY_AES);
cipher.init(Cipher.DECRYPT_MODE, deskey);
return cipher.doFinal(data);
}
private static byte[] encByAes(byte[] data) throws Exception {
SecretKey deskey = new SecretKeySpec(AES_KEY.getBytes(), KEY_AES);
Cipher cipher = Cipher.getInstance(KEY_AES);
cipher.init(Cipher.ENCRYPT_MODE, deskey);
return cipher.doFinal(data);
}
public static void main(String[] args) throws Exception {
System.out.println("DES金鑰:\n" + DES_KEY);
System.out.println("DES金鑰位元組長度:\n" + DES_KEY.getBytes().length);
String word = "123";
System.out.println("原文:" + word);
System.out.println("=============DES=============");
byte b[] = encByDes(word.getBytes());
String encWord = new String(b);
System.out.println("加密後:" + encWord);
System.out.println("解密後:" + new String(decByDes(b)));
System.out.println("=============3DES=============");
System.out.println("3DES金鑰:" + DES_3_KEY);
System.out.println("3DES金鑰位元組長度:" + DES_3_KEY.getBytes().length);
b = encBy3Des(word.getBytes());
encWord = new String(b);
System.out.println("加密後:" + encWord);
System.out.println("解密後:" + new String(decBy3Des(b)));
System.out.println("=============AES=============");
System.out.println("AES金鑰:" + AES_KEY);
System.out.println("AES金鑰位元組長度:" + AES_KEY.getBytes().length);
b = encByAes(word.getBytes());
encWord = new String(b);
System.out.println("加密後:" + encWord);
System.out.println("解密後:" + new String(decByAes(b)));
}
}
RSA非對稱加密
/**
* Project Name:thread
* File Name:RSAUtil.java
* Package Name:enc.dec
* Date:2015年10月22日上午9:21:01
* Copyright (c) 2015, [email protected] All Rights Reserved.
*
*/
package enc.dec;
import java.io.ByteArrayOutputStream;
import java.security.Key;
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;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
import com.alibaba.fastjson.JSONObject;
/**
* ClassName:RSAUtil <br/>
* Function: TODO ADD FUNCTION. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2015年10月22日 上午9:21:01 <br/>
*
* @author chiwei
* @version
* @since JDK 1.6
* @see
*/
public class RSAUtil {
/**
* 加密演算法RSA
*/
public static final String KEY_ALGORITHM = "RSA";
/**
* 簽名演算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
* 獲取公鑰的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey";
private static final int keyLen = 512;// 金鑰長度
/**
* 獲取私鑰的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey";
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = keyLen / 8 - 11;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = keyLen / 8;
/**
*
* genKeyPair:(). <br/>
* 生成公司鑰對,返回的是經過BASE64編碼的金鑰
* @author chiwei
* @return
* @throws Exception
* @since JDK 1.6
*/
public static Map<String, Object> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(keyLen);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
*
* sign:(). <br/>
* 用私鑰進行簽名,返回BASE64編碼的內容
* @author chiwei
* @param data
* @param privateKey
* @return
* @throws Exception
* @since JDK 1.6
*/
public static String sign(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64Util.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(data);
return Base64Util.encode(signature.sign());
}
/**
*
* verify:(). <br/>
* 用公鑰對簽名進行驗證
* @author chiwei
* @param data
* @param publicKey
* @param sign
* @return
* @throws Exception
* @since JDK 1.6
*/
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
byte[] keyBytes = Base64Util.decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(data);
return signature.verify(Base64Util.decode(sign));
}
/**
*
* decryptByPrivateKey:(). <br/>
* 私鑰解密
* @author chiwei
* @param encryptedData
* @param privateKey
* @return
* @throws Exception
* @since JDK 1.6
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)
throws Exception {
byte[] keyBytes = Base64Util.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 對資料分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
*
* decryptByPublicKey:(). <br/>
* 公鑰解密
* @author chiwei
* @param encryptedData
* @param publicKey
* @return
* @throws Exception
* @since JDK 1.6
*/
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)
throws Exception {
byte[] keyBytes = Base64Util.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 對資料分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
*
* encryptByPublicKey:(). <br/>
* 公鑰加密
* @author chiwei
* @param data
* @param publicKey
* @return
* @throws Exception
* @since JDK 1.6
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
byte[] keyBytes = Base64Util.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 對資料加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 對資料分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
*
* encryptByPrivateKey:(). <br/>
* 私鑰加密
* @author chiwei
* @param data
* @param privateKey
* @return
* @throws Exception
* @since JDK 1.6
*/
public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64Util.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 對資料分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
*
* getPrivateKey:(). <br/>
* 獲取BASE64編碼的私鑰
* @author chiwei
* @param keyMap
* @return
* @throws Exception
* @since JDK 1.6
*/
public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return Base64Util.encode(key.getEncoded());
}
/**
*
* getPublicKey:(). <br/>
* 獲取BASE64編碼的公鑰
* @author chiwei
* @param keyMap
* @return
* @throws Exception
* @since JDK 1.6
*/
public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return Base64Util.encode(key.getEncoded());
}
public static void main(String args[]) {
JSONObject json = new JSONObject();
json.put("deviceId", "1");
json.put("clientVersion", "2");
json.put("platform", "1");
JSONObject position = new JSONObject();
position.put("location_latitude_key", "10.98");
position.put("location_longtitude_key", "110.98");
json.put("position", position);
json.put("city", "杭州市");
json.put("locatedAddress", "");
json.put("romVersion", "1");
json.put("commandId", 0x125);
json.put("userId", 10049);
json.put("orderId", 10053);
System.out.println(json);
String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIc7AHO19/BdTKI18QDeqOxHCNHI w8+2C15kvE5h+kYoQxCq3IdVDsJJKFJSAtfOe7WHgLUDOpAZaHcUnpW7HpUC AwEAAQ==";// "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZozfHvyz7LZIAo7BPX2HE DHc4CZR9UIwPC/omfaJ62f8l2na+YRKQHBE220+RQfqupVMKmy7QYo+hAjs4 MqCgCedqyWBwHhrhTbQp5FuZ/xaqFCuz/ntyYzz7NrYoD3ijtwBXUrx6kTJf xtkB/Nhd317JHuzxPR9bNUj3K5pLfwIDAQAB";
String privateKey = "MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAhzsAc7X38F1M ojXxAN6o7EcI0cjDz7YLXmS8TmH6RihDEKrch1UOwkkoUlIC1857tYeAtQM6 kBlodxSelbselQIDAQABAkBwhC4XGMPoMajumpUhFSJWHbB/5FzQOXbyHjzz tt/neKONwuB25QJ+DehwtKGnjDtcrSlUbNYIc0L95eKPGvJBAiEA39pNrReU WThfcQkz1TEmL+Pqh09Uf5KdkUJFRn3rEsUCIQCapplvyKoWiC2//J8NXUds 1SyNv5+vsXlwhtPqJsNZkQIgEEIy0hecVr6ZcARTF3DybRgIuLsyT/G+MAa4 MV6D7GECICocr6+G3vofvwWGjvEes3JpYiZ/Rcab90uzC0W5pHxhAiAvPq16 AvszXkXVZXgvEHoyG2qvbj0I7VkCsHI8C0E1xQ==";// "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJmjN8e/LPst kgCjsE9fYcQMdzgJlH1QjA8L+iZ9onrZ/yXadr5hEpAcETbbT5FB+q6lUwqb LtBij6ECOzgyoKAJ52rJYHAeGuFNtCnkW5n/FqoUK7P+e3JjPPs2tigPeKO3 AFdSvHqRMl/G2QH82F3fXske7PE9H1s1SPcrmkt/AgMBAAECf0sEZzghINWE asXlJzGaYSJY891o0BhgPAMc1gf1UGCsEOlqwpAy1d2H1t/yNee3T6/3CZUk MLePaJI1hLTsA4FcGzEWKUy7Hn2CqIjUzkJdax6CYXlK0hcoI47fiCr7Wtcx U/6P1uN+shA5ICHF0nZYJ2vEO1Vw/xMVGnLIRykCQQDwHJ0yOJZde7nZxo56 xka2C1tfMNjziXkdFH6EGfaiT0iJkJ+Kd11m0LukUxLPo5U1O63ZYkWOtFen wL2FmJTzAkEAo83FAO23KDZAyaPJg4K1PWqScF8+BDK51QxmJR0iCcl2umck jTfnO53wE8zjGNH/nqKQK6D+RUs8vEWaI37CRQJBAKKEW4mQb4XappJWKD3F UjsJONEXOOCtncInCvLSt/JoA0rJDpMj854Rjc/NQqAzslwThrnqH/ZU7jdm 52AzRC0CQB62djm2WKExivRDwYTm/RSG5u4q7XXcDPvlV0GeNMOhAqHwtOnF kZWcB2evAuWkeklEMcP8a7CSatDiPARrwAECQQC0SMsT/xukGzOh4SkHEirN bdFwdLdFeJf+8O3Tsf7iYlTNhnGEgTLQeaf3xOoivGtJEXZwT7vJWtiTUXRW 8P1v";
try {
// Map key = genKeyPair();
// publicKey = getPublicKey(key);
// privateKey = getPrivateKey(key);
System.out.println("公鑰-->" + publicKey);
System.out.println("私鑰-->" + privateKey);
System.out.println("待加密的字串:" + json);
byte[] enBy = encryptByPublicKey(json.toJSONString().getBytes(), publicKey);
String enStr = new String(enBy, "UTF-8");
System.out.println("加密後:" + enStr);
String enEncode = Base64Util.encode(enBy);
System.out.println("加密後編碼內容:" + enEncode);
byte[] deBy = decryptByPrivateKey(Base64Util.decode(enEncode), privateKey);
System.out.println("解密後:" + new String(deBy));
System.out.println("解密後編碼內容:" + Base64Util.encode(deBy));
String sign = sign(enBy,privateKey);
System.out.println("簽名:"+sign);
System.out.println("對簽名驗證:"+verify(enBy, publicKey, sign));
System.out.println("BASE64編碼密文摘要:"+MD5Util.getMD5(enEncode));
} catch (Exception e) {
e.printStackTrace();
}
}
}
資料加密:
為了保證資料的安全性,不會洩露資料的真是內容
資料摘要:
為了確保資料中途沒有被篡改過,資料的內容時完整的正確的
資料簽名:
為了保證資料是對方過來的,而不是從別的地方來的
在真實的網際網路應用中,加密場景非常重要
1、對資料加密
2、對密文生成摘要
3、對摘要進行簽名
4、將密文和簽名一起傳送
這樣就保證了資料的安全性
這裡還有一個唯一的漏洞就是接收方的公鑰被人替換了,所以就出現了證書認證中心
確保公鑰的安全性,在傳送資料的時候加上數字證書。
相關推薦
【JAVA】常用加解密演算法總結及JAVA實現【BASE64,MD5,SHA,DES,3DES,AES,RSA】
BASE64 這其實是一種編解碼方法,但是隻要我們能夠將原文變成肉眼不可識別的內容,其實就是一種加密的方法。 BASE64 的編碼都是按字串長度,以每 3 個 8 bit 的字元為一組,然後針對每組,首先獲取每個字元的 ASCII 編碼,然後將 ASCII 編碼轉換成 8
golang常用加密解密演算法總結(AES、DES、RSA、Sha1MD5)
在專案開發過程中,當操作一些使用者的隱私資訊,諸如密碼、帳戶金鑰等資料時,往往需要加密後可以在網上傳輸。這時,需要一些高效地、簡單易用的加密演算法加密資料,然後把加密後的資料存入資料庫或進行其他操作;當需要讀取資料時,把加密後的資料取出來,再通過演算法解密。 關於加密解密 當前我們專案中常用
Java☞DES加解密演算法簡介及實現
Java加密解密之對稱加密演算法DES 資料加密演算法(Data Encryption Algorithm,DEA)是一種對稱加密演算法,很可能是使用最廣泛的金鑰系統,特別是在保護金融資料的安全中,最初開發的DEA是嵌入硬體中的。通常,自動取款機(Aut
【轉載】常用資料增強方法總結及實現
【參考資料】論文:ImageNet Classification with Deep Convolutional Neural Networks【常用方法】1、Color Jittering:對顏色的資料增強:影象亮度、飽和度、對比度變化(此處對色彩抖動的理解不知是否得當);
最強加密演算法?AES加解密演算法Matlab和Verilog實現
目錄 背景 AES加密的幾種模式 基本運算 AES加密原理 Matlab實現 Verilog實現 Testbench 本文首發於公眾號【兩猿社】,重點講述了AES加密演算法的加密模式和原理,用MATLAB和Verilog進行加解密的實現。 美劇《矽谷》第六季居然已經完結了!小猿追了6年的劇就這麼結束
【網路安全】加解密演算法最詳解
資料簽名、加密是前後端開發經常需要使用到的技術,應用場景包括不限於使用者登入、資料交易、資訊通訊等,不同的應用場景也會需要使用到不同的簽名加密演算法,或者需要搭配不一樣的 簽名加密演算法來達到業務目標。常用的加密演算法有: 對稱加密演算法; 非對稱加密演算法; 雜湊演算法,加鹽雜湊演算法(單向加密); 數
【極客時間】資料結構與演算法總結
【極客時間】資料結構與演算法總結: 02| 資料結構是為演算法服務的,演算法要作用在特定的資料結構之上。 20個最常用的最基礎的資料結構與演算法: 10個數據結構:陣列、連結串列、棧、佇列、散列表、二叉樹、堆、跳錶、圖、Trie樹 10個演算法:遞迴、排序、二分
常用排序演算法總結(Java實現)
排序演算法比較: 1. 氣泡排序 /** * 氣泡排序 * 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。 * 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。 * 針對所有的元素重複以上的步驟,除了最後一個
【面試複習系列】常用機器學習演算法知識點及其解析,面試官會考的幾乎都有,歡迎補充
圖片慢慢上傳,看不到圖片的請點這裡: LR:logistic regression 對數機率迴歸/邏輯迴歸 sigmoid函式的作用就是用於把輸出歸一到1和0,也就
【java版】資料結構與演算法分析學習之路【一】前言
一.資料結構和演算法概述?【框範圍】 基礎資料結構主要包括表【陣列+連結串列】、棧、佇列【散列表】、樹、圖、堆。高階資料結構包括伸展樹、紅黑樹、確定性跳躍表、AA樹、treap樹、k-d樹、配對堆。
時間複雜度為O(N*logN)的常用排序演算法總結與Java實現
時間複雜度為O(N*logN)的常用排序演算法主要有四個——快速排序、歸併排序、堆排序、希爾排序1.快速排序·基本思想 隨機的在待排序陣列arr中選取一個元素作為標記記為arr[index](有時也直接選擇起始位置),然後在arr中從後至前以下標j尋找比arr[inde
【機器學習】常用聚類演算法原型
1. 聚類簡介 在機器學習中,分為監督學習、無監督學習和半監督學習。前一篇部落格中提到的迴歸和分類都屬於監督學習,本文著重探討無監督學習中的聚類演算法。 博主之前看過一些資料,這兩天也翻閱了網上的各大部落格後,也想總結一下,寫一寫聚類相關的知識點,對
Java基礎之加解密(三) SHA安全雜湊演算法
介紹:安全雜湊演算法(Secure Hash Algorithm)主要適用於數字簽名標準(Digital Signature Standard DSS)裡面定義的數字簽名演算法(Digital Signature Algorithm DSA)。該演算法的思想是接收一段明文,
java 常用加密解密演算法彙總(一)
http://blog.csdn.net/chenbing81/article/details/51914151 http://www.cnblogs.com/crazylqy/p/4816587.html
【PHP基礎知識】——常用字串處理函式總結
一、概要 我們知道,字串操作是主流web程式語言的基礎,也是在日常開發中不可或缺的一項。PHP處理字串的能力非常強大,方法也是多種多樣。文章列舉了一些PHP中常見的字串處理方法。二、常用字串處理方法 1、判斷一個字串的長度:intstrlen ( string $strin
C#/JAVA/PHP 互通DES加解密演算法(ECB模式支援8位)
import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingE
3DES加解密演算法
在日常設計及開發中,為確保資料傳輸和資料儲存的安全,可通過特定的演算法,將資料明文加密成複雜的密文。目前主流加密手段大致可分為單向加密和雙向加密。 單向加密:通過對資料進行摘要計算生成密文,密文不可逆推還原。演算法代表:Base64,MD5,SHA; 雙向加密:與單向加密相
深度學習除錯網路時常用的優化演算法總結
自己的小專案在實際除錯中出現過的優化模型的演算法,這裡做一個總結。 1、 學習率調整(避免欠擬合) 2、 正則化(避免過擬合) 3、 Dropout(避免過擬合) 4、 提前終止(避免過擬合) 學習率調整: 在訓練網路的時候,已不變的學習率學習往往不能找到最優解,從而使loss值
PHP中常用加解密方式
PHP中使用OpenSSL生成RSA公鑰私鑰及進行加密解密示例(非對稱加密) php服務端與客戶端互動、提供開放api時,通常需要對敏感的部分api資料傳輸進行資料加密,這時候rsa非對稱加密就能派上用處了,下面通過一個例子來說明如何用php來實現資料的加密解密 一、公鑰加密 假設一下,我找了兩個數字,
使用python實現RSA加解密演算法(包含讀取檔案操作),檔案內容為16進位制字串,同時實現對學號姓名的加密——(SCU應用密碼學實驗)
#-*- coding:UTF-8 -*- ''' time: 2018-5-30 content:RSA python 3.6 mac os ''' from random import randint import random im