為了數(shù)據(jù)安全我們?cè)陂_發(fā)過程中經(jīng)常會(huì)對(duì)重要的數(shù)據(jù)進(jìn)行加密存儲(chǔ),常見的有:密碼、手機(jī)號(hào)、電話號(hào)碼、詳細(xì)地址、銀行卡號(hào)、信用卡驗(yàn)證碼等信息,這些信息對(duì)加解密的要求也不一樣,比如說密碼我們需要加密存儲(chǔ),一般使用的 AES 、DES 、或者不可逆的慢 hash 算法(慢 hash嚴(yán)格來說不叫加密,因?yàn)榧用芤罂赡?,在檢索時(shí)我們既不需要解密也不需要模糊查找,直接使用密文完全匹配,但是手機(jī)號(hào)就不能這樣做,因?yàn)槭謾C(jī)號(hào)我們要查看原信息,并且對(duì)手機(jī)號(hào)還需要支持模糊查找,下面是三種可落地的針對(duì)可逆加解密的數(shù)據(jù)支持模糊查詢的實(shí)現(xiàn)方式。
同態(tài)加密方案
同態(tài)加密方案是一種特殊的加密技術(shù),允許在加密狀態(tài)下進(jìn)行計(jì)算,而不需要暴露明文數(shù)據(jù)。在同態(tài)加密方案中,加密的數(shù)據(jù)可以進(jìn)行加法和乘法等計(jì)算操作,同時(shí)保持?jǐn)?shù)據(jù)的加密狀態(tài)。以下是兩種常見的同態(tài)加密方案:
-
Paillier同態(tài)加密方案:這種方案基于公鑰加密算法,可以支持加法和乘法計(jì)算操作。在這種方案中,數(shù)據(jù)被加密,并使用公鑰加密算法生成一個(gè)密文。對(duì)于密文的加法計(jì)算,可以使用同態(tài)性質(zhì)直接對(duì)加密數(shù)據(jù)進(jìn)行加法操作,得到一個(gè)新的密文。對(duì)于密文的乘法計(jì)算,需要使用一種特殊的協(xié)議,例如Garbled Circuit協(xié)議,來計(jì)算加密數(shù)據(jù)的乘積。
-
Fully Homomorphic Encryption (FHE)方案:這種方案可以支持任意計(jì)算操作,包括加法、乘法、比較、排序等。FHE方案通常使用高度優(yōu)化的加密算法和計(jì)算技術(shù),例如Lattice-based加密算法和Gentry的Bootstrapping技術(shù)。FHE方案的計(jì)算效率較低,但可以實(shí)現(xiàn)高度安全的計(jì)算。
可搜索加密方案
可搜索加密方案是一種安全的加密技術(shù),允許在加密的數(shù)據(jù)集中進(jìn)行搜索和匹配,同時(shí)保護(hù)數(shù)據(jù)的隱私性。在可搜索加密方案中,搜索關(guān)鍵字被加密,然后與加密的數(shù)據(jù)進(jìn)行比較,以確定是否匹配。以下是一些常見的可搜索加密方案:
-
基于單詞加密的方案:這種方案用于對(duì)文本數(shù)據(jù)進(jìn)行加密搜索。在這種方案中,文本數(shù)據(jù)被分解成單詞,然后對(duì)每個(gè)單詞進(jìn)行加密。搜索時(shí),搜索關(guān)鍵字也被分解成單詞,并對(duì)每個(gè)單詞進(jìn)行加密。然后,加密的關(guān)鍵字與加密的單詞進(jìn)行比較,以確定是否匹配。
-
基于布隆過濾器的方案:這種方案使用布隆過濾器對(duì)加密的數(shù)據(jù)進(jìn)行索引。布隆過濾器是一種高效的數(shù)據(jù)結(jié)構(gòu),可以用于檢查一個(gè)元素是否屬于一個(gè)集合中。在這種方案中,搜索關(guān)鍵字被加密,并用于查詢布隆過濾器。如果布隆過濾器返回一個(gè)匹配,那么就可以在相應(yīng)的數(shù)據(jù)項(xiàng)中進(jìn)一步查找。
-
基于密文索引的方案:這種方案使用密文索引來存儲(chǔ)加密的數(shù)據(jù)。密文索引是一種數(shù)據(jù)結(jié)構(gòu),可以用于存儲(chǔ)加密的數(shù)據(jù),并支持在加密狀態(tài)下進(jìn)行搜索和匹配。在這種方案中,搜索關(guān)鍵字被加密,并與密文索引進(jìn)行比較,以確定是否匹配。
基于數(shù)據(jù)庫特性加解密
在數(shù)據(jù)庫中實(shí)現(xiàn)與程序一致的加解密算法,修改模糊查詢條件,使用數(shù)據(jù)庫加解密函數(shù)先解密再模糊查找,這樣做的優(yōu)點(diǎn)是實(shí)現(xiàn)成本較低,只需要將以往的模糊查找稍微修改一下就可以實(shí)現(xiàn),但是缺點(diǎn)也很明顯,這樣做無法利用數(shù)據(jù)庫的索引來優(yōu)化查詢,甚至有一些數(shù)據(jù)庫可能無法保證與程序?qū)崿F(xiàn)一致的加解密算法,但是對(duì)于常規(guī)的加解密算法都可以保證與應(yīng)用程序一致。
如果對(duì)查詢性能要求不是特別高、對(duì)數(shù)據(jù)安全性要求一般,可以使用常見的加解密算法比如說AES、DES之類的也是一個(gè)不錯(cuò)的選擇。
參考資料:
https://www.jianshu.com/p/b11816770d46
https://github.com/digoal/blog/blob/master/201710/20171020_01.md
缺點(diǎn):
性能較差,對(duì)于 pg 和 mysql 不同的數(shù)據(jù)庫單獨(dú)開發(fā),對(duì) ES 無法支持
基于單詞加密的方案
對(duì)密文數(shù)據(jù)進(jìn)行分詞組合,將分詞組合的結(jié)果集分別進(jìn)行加密,然后存儲(chǔ)到擴(kuò)展列,查詢時(shí)通過key like ‘%partial%’,這是一個(gè)比較劃算的實(shí)現(xiàn)方法,我們先來分析一下它的實(shí)現(xiàn)思路。
先對(duì)字符進(jìn)行固定長度的分組,將一個(gè)字段拆分為多個(gè),比如說根據(jù) 4 位英文字符(半角),2 個(gè)中文字符(全角)為一個(gè)檢索條件,舉個(gè)例子:
ningyu1使用4個(gè)字符為一組的加密方式,第一組ning ,第二組ingy ,第三組ngyu ,第四組gyu1 … 依次類推。
如果需要檢索所有包含檢索條件 4 個(gè)字符的數(shù)據(jù)比如:ingy ,加密字符后通過 key like “%partial%” 查庫。
我們都知道加密后長度會(huì)增長,增長的這部分長度存儲(chǔ)就是我們要花費(fèi)的額外成本,典型的使用成本來換取速度,密文增長的幅度隨著算法不同而不同以DES舉例,13800138000加密前占11個(gè)字節(jié),加密后的串HE9T75xNx6c5yLmS5l4r6Q==占24個(gè)字節(jié),增長是2.18倍
這個(gè)方法雖然可以實(shí)現(xiàn)加密數(shù)據(jù)的模糊查詢,但是對(duì)模糊查詢的字符長度是有要求的,以我上面舉的例子模糊查詢字符原文長度必須大于等于 4 個(gè)英文/數(shù)字,或者 2 個(gè)漢字,再短的長度不建議支持,因?yàn)榉衷~組合會(huì)增多從而導(dǎo)致存儲(chǔ)的成本增加,反而安全性降低。
示例代碼
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class WordEncryption {
public static void main(String[] args) {
// Example text data to be encrypted
String plaintext = "This is a test text.";
// Split the plaintext into words
String[] words = plaintext.split(" ");
// Generate a secret key and a public key
KeyPair keyPair = generateKeyPair();
PublicKey publicKey = keyPair.getPublicKey();
SecretKey secretKey = keyPair.getSecretKey();
// Encrypt each word using the public key
List<byte[]> encryptedWords = new ArrayList<>();
for (String word : words) {
byte[] encryptedWord = encrypt(word.getBytes(), publicKey);
encryptedWords.add(encryptedWord);
}
// Search for a keyword in the encrypted words
String keyword = "test";
byte[] encryptedKeyword = encrypt(keyword.getBytes(), publicKey);
for (int i = 0; i < encryptedWords.size(); i++) {
byte[] encryptedWord = encryptedWords.get(i);
if (Arrays.equals(encryptedWord, encryptedKeyword)) {
System.out.println("Found keyword \"" + keyword + "\" at index " + i);
}
}
// Decrypt a word using the secret key
byte[] encryptedWord = encryptedWords.get(0);
byte[] decryptedWord = decrypt(encryptedWord, secretKey);
String plaintextWord = new String(decryptedWord);
System.out.println("Decrypted word: " + plaintextWord);
}
// Generate a public-private key pair
private static KeyPair generateKeyPair() {
// TODO: Implement key pair generation using a suitable algorithm
return null;
}
// Encrypt a plaintext message using a public key
private static byte[] encrypt(byte[] plaintext, PublicKey publicKey) {
// TODO: Implement encryption using a suitable algorithm
return null;
}
// Decrypt a ciphertext message using a secret key
private static byte[] decrypt(byte[] ciphertext, SecretKey secretKey) {
// TODO: Implement decryption using a suitable algorithm
return null;
}
}
// Key pair class for holding public and secret keys
class KeyPair {
private PublicKey publicKey;
private SecretKey secretKey;
public KeyPair(PublicKey publicKey, SecretKey secretKey) {
this.publicKey = publicKey;
this.secretKey = secretKey;
}
public PublicKey getPublicKey() {
return publicKey;
}
public SecretKey getSecretKey() {
return secretKey;
}
}
// Public key class for encryption
class PublicKey {
// TODO: Implement public key data and methods
}
// Secret key class for decryption
class SecretKey {
// TODO: Implement secret key data and methods
}
參考資料:
https://open.taobao.com/docV3.htm?docId=106213&docType=1
缺點(diǎn):
- 對(duì)不同類型的字段要不同處理,比如純數(shù)字、純英文、中文
- 不夠靈活,英文只能模糊檢索四位,中文只能模糊檢索兩位
- 用于檢索的密文擴(kuò)展字段占用空間較多
基于布隆過濾器的方案
這種方案使用布隆過濾器對(duì)加密的數(shù)據(jù)進(jìn)行索引。布隆過濾器是一種高效的數(shù)據(jù)結(jié)構(gòu),可以用于檢查一個(gè)元素是否屬于一個(gè)集合中。在這種方案中,搜索關(guān)鍵字被加密,并用于查詢布隆過濾器。如果布隆過濾器返回一個(gè)匹配,那么就可以在相應(yīng)的數(shù)據(jù)項(xiàng)中進(jìn)一步查找。
示例代碼
import java.util.BitSet;
public class BloomFilterEncryption {
public static void main(String[] args) {
// Example text data to be encrypted
String plaintext = "This is a test text.";
// Generate a secret key and a public key
KeyPair keyPair = generateKeyPair();
PublicKey publicKey = keyPair.getPublicKey();
SecretKey secretKey = keyPair.getSecretKey();
// Build a Bloom filter index of the encrypted words
int numWords = 1000; // number of words to index
int numBits = 10000; // number of bits in the Bloom filter
int numHashes = 3; // number of hash functions to use
BloomFilter bloomFilter = new BloomFilter(numBits, numHashes);
for (int i = 0; i < numWords; i++) {
// Generate a random word to encrypt
String word = generateRandomWord();
// Encrypt the word using the public key
byte[] encryptedWord = encrypt(word.getBytes(), publicKey);
// Add the encrypted word to the Bloom filter
bloomFilter.add(encryptedWord);
}
// Search for a keyword in the Bloom filter
String keyword = "test";
byte[] encryptedKeyword = encrypt(keyword.getBytes(), publicKey);
boolean exists = bloomFilter.contains(encryptedKeyword);
if (exists) {
System.out.println("Found keyword \"" + keyword + "\" in the Bloom filter.");
} else {
System.out.println("Keyword \"" + keyword + "\" not found in the Bloom filter.");
}
}
// Generate a public-private key pair
private static KeyPair generateKeyPair() {
// TODO: Implement key pair generation using a suitable algorithm
return null;
}
// Generate a random word
private static String generateRandomWord() {
// TODO: Implement random word generation
return null;
}
// Encrypt a plaintext message using a public key
private static byte[] encrypt(byte[] plaintext, PublicKey publicKey) {
// TODO: Implement encryption using a suitable algorithm
return null;
}
// Decrypt a ciphertext message using a secret key
private static byte[] decrypt(byte[] ciphertext, SecretKey secretKey) {
// TODO: Implement decryption using a suitable algorithm
return null;
}
}
// Key pair class for holding public and secret keys
class KeyPair {
private PublicKey publicKey;
private SecretKey secretKey;
public KeyPair(PublicKey publicKey, SecretKey secretKey) {
this.publicKey = publicKey;
this.secretKey = secretKey;
}
public PublicKey getPublicKey() {
return publicKey;
}
public SecretKey getSecretKey() {
return secretKey;
}
}
// Public key class for encryption
class PublicKey {
// TODO: Implement public key data and methods
}
// Secret key class for decryption
class SecretKey {
// TODO: Implement secret key data and methods
}
// Bloom filter class for indexing encrypted words
class BloomFilter {
private BitSet bitset;
private int numHashes;
public BloomFilter(int numBits, int numHashes) {
this.bitset = new BitSet(numBits);
this.numHashes = numHashes;
}
public void add(byte[] data) {
for (int i = 0; i < numHashes; i++) {
int hash = hash(data, i);
bitset.set(hash, true);
}
}
public boolean contains(byte[] data) {
for (int i = 0; i < numHashes; i++) {
int hash = hash(data, i);
if (!bitset.get(hash)) {
return false;
}
}
return true;
}
private int hash(byte[] data, int index) {
// TODO: Implement a suitable hash function
return 0;
}
}
基于 Hash 前綴索引的加解密方案(推薦)
用于檢索的密文擴(kuò)展字段生成方式不同:
- 遍歷字段明文每個(gè)字符
- 對(duì)字符進(jìn)行 Hash 算法后取前三位
- 遍歷完成后得到長度為「字符個(gè)數(shù) * 3」的檢索擴(kuò)展字段
當(dāng)檢索時(shí):
- 遍歷檢索數(shù)據(jù)每個(gè)字符
- 對(duì)字段進(jìn)行 Hash 算法后取前三位
- 遍歷完成后得到長度為「檢索字符個(gè)數(shù) * 3」的 Hash 檢索字段
- 進(jìn)行數(shù)據(jù)庫的模糊匹配 like “% Hash 檢索字段 %”
示例代碼
-
encryptField 方法用于對(duì)字段進(jìn)行加密,遍歷字段明文的每個(gè)字符,對(duì)字符進(jìn)行 Hash 算法加密后取前三位,遍歷完成后得到長度為「字符個(gè)數(shù) * 3」的密文擴(kuò)展字段。
-
encryptKeyword 方法用于對(duì)檢索條件進(jìn)行加密,遍歷檢索數(shù)據(jù)的每個(gè)字符,對(duì)字符進(jìn)行 Hash 算法加密后取前三位,遍歷完成后得到長度為「檢索字符個(gè)數(shù) * 3」的加密檢索字段。
-
fuzzyMatch 方法用于執(zhí)行模糊匹配,接收一個(gè)加密字段列表和一個(gè)加密后的檢索字段,遍歷加密字段列表中的每個(gè)字段,檢查字段是否包含加密后的檢索字段,如果包含則將該字段添加到匹配結(jié)果列表中。
為了實(shí)現(xiàn) Hash 算法的加密,我們使用了 Java 自帶的 MessageDigest 類,并將其初始化為 SHA-256 算法。在對(duì)單個(gè)字符進(jìn)行 Hash 加密時(shí),我們首先將字符轉(zhuǎn)換為字節(jié)數(shù)組,然后使用 update 方法更新 MessageDigest 對(duì)象的狀態(tài),最后使用 digest 方法生成字節(jié)數(shù)組的 Hash 值,并將其轉(zhuǎn)換為十六進(jìn)制字符串,最終返回字符串的前三位。
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;
public class SearchableEncryption {
private static final String ENCRYPTION_ALGORITHM = "SHA-256";
/**
* 加密字段
*
* @param plaintext 待加密的字段明文
* @return 密文擴(kuò)展字段
*/
public static String encryptField(String plaintext) throws Exception {
MessageDigest messageDigest = MessageDigest.getInstance(ENCRYPTION_ALGORITHM);
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < plaintext.length(); i++) {
String hash = hash(messageDigest, plaintext.charAt(i));
stringBuilder.append(hash);
}
return stringBuilder.toString();
}
/**
* 加密檢索條件
*
* @param keyword 待檢索的關(guān)鍵字
* @return 加密后的檢索字段
*/
public static String encryptKeyword(String keyword) throws Exception {
MessageDigest messageDigest = MessageDigest.getInstance(ENCRYPTION_ALGORITHM);
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < keyword.length(); i++) {
String hash = hash(messageDigest, keyword.charAt(i));
stringBuilder.append(hash);
}
return stringBuilder.toString();
}
/**
* 執(zhí)行模糊匹配
*
* @param database 數(shù)據(jù)庫中存儲(chǔ)的加密字段列表
* @param keyword 加密后的檢索字段
* @return 匹配的結(jié)果列表
*/
public static List<String> fuzzyMatch(List<String> database, String keyword) {
List<String> results = new ArrayList<>();
for (String field : database) {
if (field.contains(keyword)) {
results.add(field);
}
}
return results;
}
/**
* 對(duì)單個(gè)字符進(jìn)行 Hash 加密并截取前三位
*
* @param messageDigest 加密算法
* @param ch 待加密字符
* @return 加密結(jié)果的前三位
*/
private static String hash(MessageDigest messageDigest, char ch) throws Exception {
messageDigest.update(String.valueOf(ch).getBytes());
byte[] digest = messageDigest.digest();
String hash = bytesToHex(digest);
return hash.substring(0, 3);
}
/**
* 將字節(jié)數(shù)組轉(zhuǎn)換成十六進(jìn)制字符串
*
* @param bytes 待轉(zhuǎn)換字節(jié)數(shù)組
* @return 轉(zhuǎn)換后的十六進(jìn)制字符串
*/
private static String bytesToHex(byte[] bytes) {
StringBuilder stringBuilder = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xFF & b);
if (hex.length() == 1) {
stringBuilder.append('0');
}
stringBuilder.append(hex);
}
return stringBuilder.toString();
}
}
參考資料:
https://jos.jd.com/commondoc?listId=345
缺點(diǎn):
- 有極小概率檢索到多余的數(shù)據(jù)
- Hash 算法需要帶密鑰防止破解
Hash 算法介紹
Hash 函數(shù)又稱單向散列函數(shù)(one-way hash function)是指對(duì)不同的輸入值,通過單向散列函數(shù)進(jìn)行計(jì)算,得到固定長度的輸出值。這個(gè)輸入值稱為消息(message),輸出值稱為散列值(hash value)。
常用的 Hash 算法有很多種,每種算法都有自己的特點(diǎn)和優(yōu)缺點(diǎn)。下面是幾種常見的 Hash 算法對(duì)比:
MD5(Message-Digest Algorithm 5)
MD5 是一種廣泛使用的 Hash 算法,其輸出長度為 128 位。雖然 MD5 有一定的安全性,但由于其輸出長度較短,存在被暴力破解的風(fēng)險(xiǎn)。
SHA-1(Secure Hash Algorithm 1)
SHA-1 是一種常用的 Hash 算法,其輸出長度為 160 位。SHA-1 的安全性比 MD5 更高,但由于其輸出長度較短,也存在被暴力破解的風(fēng)險(xiǎn)。
SHA-2(Secure Hash Algorithm 2)
SHA-2 是一種比 SHA-1 更安全的 Hash 算法族,包括 SHA-224、SHA-256、SHA-384 和 SHA-512 四種算法。SHA-256 是其中應(yīng)用最廣泛的一種,其輸出長度為 256 位。SHA-2 算法具有更高的安全性和更長的輸出長度,但也需要更多的計(jì)算資源和時(shí)間。
SHA-3(Secure Hash Algorithm 3)
SHA-3 是一種最新的 Hash 算法,由美國國家標(biāo)準(zhǔn)與技術(shù)研究院(NIST)于 2015 年發(fā)布。SHA-3 算法的安全性和效率都比 SHA-2 更高,但其應(yīng)用較為局限,目前尚未得到廣泛應(yīng)用。
總的來說,選擇哪種 Hash 算法取決于具體的應(yīng)用場景和安全要求。一般來說,為了保證數(shù)據(jù)的安全性,應(yīng)選擇輸出長度較長的 Hash 算法,如 SHA-2 算法族或 SHA-3 算法。同時(shí),在實(shí)際應(yīng)用中,還需要考慮算法的性能和適用性等方面的因素。文章來源:http://www.zghlxwxcb.cn/news/detail-571432.html
代碼實(shí)現(xiàn):
JDK的 java.security.MessageDigest 類為我們提供了消息摘要算法,用于 MD5 和 SHA 的散列值生成。下面代碼做了簡單的封裝,便于直接使用。Java8 還不支持 SHA-3,從 Java9 開始支持 SHA-3文章來源地址http://www.zghlxwxcb.cn/news/detail-571432.html
public class MDUtil {
/**
* MD5
*
* @param data 要哈希的數(shù)據(jù)
* @return 32 位十六進(jìn)制字符串
*/
public static String MD5(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] bytes = md.digest(data);
return bytesToHexString(bytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* MD5
*
* @param data 要哈希的數(shù)據(jù)
* @return 32位十六進(jìn)制字符串
*/
public static String MD5(String data) {
return MD5(data.getBytes());
}
/**
* SHA-1
*
* @param data 要哈希的數(shù)據(jù)
* @return 40 位十六進(jìn)制字符串
*/
public static String SHA1(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] bytes = md.digest(data);
return bytesToHexString(bytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* SHA-1
*
* @param data 要哈希的數(shù)據(jù)
* @return 40 位十六進(jìn)制字符串
*/
public static String SHA1(String data) {
return SHA1(data.getBytes());
}
/**
* SHA-224
*
* @param data 要哈希的數(shù)據(jù)
* @return 56 位十六進(jìn)制字符串
*/
public static String SHA224(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-224");
byte[] bytes = md.digest(data);
return bytesToHexString(bytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* SHA-224
*
* @param data 要哈希的數(shù)據(jù)
* @return 56 位十六進(jìn)制字符串
*/
public static String SHA224(String data) {
return SHA224(data.getBytes());
}
/**
* SHA-256
*
* @param data 要哈希的數(shù)據(jù)
* @return 64 位十六進(jìn)制字符串
*/
public static String SHA256(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] bytes = md.digest(data);
return bytesToHexString(bytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* SHA-256
*
* @param data 要哈希的數(shù)據(jù)
* @return 64 位十六進(jìn)制字符串
*/
public static String SHA256(String data) {
return SHA256(data.getBytes());
}
/**
* SHA-384
*
* @param data 要哈希的數(shù)據(jù)
* @return 96 位十六進(jìn)制字符串
*/
public static String SHA384(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-384");
byte[] bytes = md.digest(data);
return bytesToHexString(bytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* SHA-384
*
* @param data 要哈希的數(shù)據(jù)
* @return 96 位十六進(jìn)制字符串
*/
public static String SHA384(String data) {
return SHA384(data.getBytes());
}
/**
* SHA-512
*
* @param data 要哈希的數(shù)據(jù)
* @return 128 位十六進(jìn)制字符串
*/
public static String SHA512(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-512");
byte[] bytes = md.digest(data);
return bytesToHexString(bytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* SHA-512
*
* @param data 要哈希的數(shù)據(jù)
* @return 128 位十六進(jìn)制字符串
*/
public static String SHA512(String data) {
return SHA512(data.getBytes());
}
/**
* 將字節(jié)數(shù)組轉(zhuǎn)換為十六進(jìn)制字符串
*
* @param bytes 字節(jié)數(shù)組
* @return 十六進(jìn)制字符串
*/
private static String bytesToHexString(byte[] bytes) {
StringBuilder hexValue = new StringBuilder();
for (byte b : bytes) {
int val = b & 0xFF;
if (val < 16) {
hexValue.append("0");
}
hexValue.append(Integer.toHexString(val));
}
return hexValue.toString();
}
}
到了這里,關(guān)于字段加密支持搜索技術(shù)方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!