java cipher是什么,讓我們一起了解一下?
創(chuàng)新互聯(lián)公司專注于洛龍網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供洛龍營銷型網(wǎng)站建設(shè),洛龍網(wǎng)站制作、洛龍網(wǎng)頁設(shè)計(jì)、洛龍網(wǎng)站官網(wǎng)定制、小程序開發(fā)服務(wù),打造洛龍網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供洛龍網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
cipher是在javax.crypto包下,構(gòu)成了Java Cryptographic Extension (JCE) 框架的核心,Java的Cipher類提供了加密和解密的功能。
我們都知道,Cipher類是一個(gè)引擎類,它需要通過getInstance()工廠方法來實(shí)例化對象。那么該如何操作?
1、我們可以通過指定轉(zhuǎn)換模式的方式獲得實(shí)例化對象,方法如下所示:
// 返回實(shí)現(xiàn)指定轉(zhuǎn)換的 Cipher對象
public static Cipher getInstance(String transformation)
2、也可以在制定轉(zhuǎn)換模式的同時(shí)制定該轉(zhuǎn)換模式的提供者,方法如下所示:
// 返回實(shí)現(xiàn)指定轉(zhuǎn)換的 Cipher對象
public static Cipher getInstance(String transformation, Provider provider)
// 返回實(shí)現(xiàn)指定轉(zhuǎn)換的 Cipher對象
public static Cipher getInstance(String transformation, String provider) ?
注意這里的參數(shù)String transformation,通過如下代碼示例:
Cipher?c?=?Cipher.getInstance("DES");
上述實(shí)例化操作是一種最為簡單的實(shí)現(xiàn),并沒有考慮DES分組算法的工作模式和填充模式,可通過以下方式對其設(shè)定:
Cipher?c?=?Cipher.getInstance("DES/CBC/PKCS5Padding");
參數(shù)String transformation的格式是“算法/工作模式/填充模式”,不同的算法支持不同的工作模式以及填充模式。
另外,Java的Cipher類還提供了加密和解密的功能,那么JAVA是如何通過Cipher實(shí)現(xiàn)加密與解密的?
實(shí)戰(zhàn)操作:具體代碼如下 package?com.bsd.yx; import?java.security.Key; import?java.security.Security; import?java.text.SimpleDateFormat; import?java.util.Date; import?javax.crypto.Cipher; import?com.ibm.model.cxf.Safety; /** ?*?加密與解密 ?*?@author?tanf ?*?@date?2013-11-08 ?*/ public?class?EncryptionDecryption?{ /** *?默認(rèn)密鑰 */ private?static?String?strDefaultKey?=?"tandaly201124335"; /**?加密工具?*/ private?static?Cipher?encryptCipher?=?null; /**?解密工具?*/ private?static?Cipher?decryptCipher?=?null; /** *?將byte數(shù)組轉(zhuǎn)換為表示16進(jìn)制值的字符串,?如:byte[]{8,18}轉(zhuǎn)換為:0813,?和public?static?byte[] *?hexStr2ByteArr(String?strIn)?互為可逆的轉(zhuǎn)換過程 *? *?@param?arrB *????????????需要轉(zhuǎn)換的byte數(shù)組 *?@return?轉(zhuǎn)換后的字符串 *?@throws?Exception *? */ public?static?String?byteArr2HexStr(byte[]?arrB)?throws?Exception?{ int?iLen?=?arrB.length; //?每個(gè)byte用兩個(gè)字符才能表示,所以字符串的長度是數(shù)組長度的兩倍 StringBuffer?sb?=?new?StringBuffer(iLen?*?2); for?(int?i?=?0;?i?
基本的單向加密算法:
BASE64 嚴(yán)格地說,屬于編碼格式,而非加密算法
MD5(Message Digest algorithm 5,信息摘要算法)
SHA(Secure Hash Algorithm,安全散列算法)
HMAC(Hash Message Authentication Code,散列消息鑒別碼)
復(fù)雜的對稱加密(DES、PBE)、非對稱加密算法:
DES(Data Encryption Standard,數(shù)據(jù)加密算法)
PBE(Password-based encryption,基于密碼驗(yàn)證)
RSA(算法的名字以發(fā)明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman)
DH(Diffie-Hellman算法,密鑰一致協(xié)議)
DSA(Digital Signature Algorithm,數(shù)字簽名)
ECC(Elliptic Curves Cryptography,橢圓曲線密碼編碼學(xué))
代碼參考:
/**
*?BASE64加密
*
*?@param?key
*?@return
*?@throws?Exception
*/
public?static?String?encryptBASE64(byte[]?key)?throws?Exception?{
return?(new?BASE64Encoder()).encodeBuffer(key);
}
/**
*?MD5加密
*
*?@param?data
*?@return
*?@throws?Exception
*/
public?static?byte[]?encryptMD5(byte[]?data)?throws?Exception?{
MessageDigest?md5?=?MessageDigest.getInstance(KEY_MD5);
md5.update(data);
return?md5.digest();
}
/**
*?SHA加密
*
*?@param?data
*?@return
*?@throws?Exception
*/
public?static?byte[]?encryptSHA(byte[]?data)?throws?Exception?{
MessageDigest?sha?=?MessageDigest.getInstance(KEY_SHA);
sha.update(data);
return?sha.digest();
}
}
/**
*?初始化HMAC密鑰
*
*?@return
*?@throws?Exception
*/
public?static?String?initMacKey()?throws?Exception?{
KeyGenerator?keyGenerator?=?KeyGenerator.getInstance(KEY_MAC);
SecretKey?secretKey?=?keyGenerator.generateKey();
return?encryptBASE64(secretKey.getEncoded());
}
/**
*?HMAC加密
*
*?@param?data
*?@param?key
*?@return
*?@throws?Exception
*/
public?static?byte[]?encryptHMAC(byte[]?data,?String?key)?throws?Exception?{
SecretKey?secretKey?=?new?SecretKeySpec(decryptBASE64(key),?KEY_MAC);
Mac?mac?=?Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
return?mac.doFinal(data);
}
用java加密壓縮zip文件:
package com.ninemax.demo.zip.decrypt;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.zip.DataFormatException;
import org.apache.commons.io.FileUtils;
import de.idyl.winzipaes.AesZipFileDecrypter;
import de.idyl.winzipaes.AesZipFileEncrypter;
import de.idyl.winzipaes.impl.AESDecrypter;
import de.idyl.winzipaes.impl.AESDecrypterBC;
import de.idyl.winzipaes.impl.AESEncrypter;
import de.idyl.winzipaes.impl.AESEncrypterBC;
import de.idyl.winzipaes.impl.ExtZipEntry;
/**
* 壓縮指定文件或目錄為ZIP格式壓縮文件
* 支持中文(修改源碼后)
* 支持密碼(僅支持256bit的AES加密解密)
* 依賴bcprov項(xiàng)目(bcprov-jdk16-140.jar)
*
* @author zyh
*/
public class DecryptionZipUtil {
/**
* 使用指定密碼將給定文件或文件夾壓縮成指定的輸出ZIP文件
* @param srcFile 需要壓縮的文件或文件夾
* @param destPath 輸出路徑
* @param passwd 壓縮文件使用的密碼
*/
public static void zip(String srcFile,String destPath,String passwd) {
AESEncrypter encrypter = new AESEncrypterBC();
AesZipFileEncrypter zipFileEncrypter = null;
try {
zipFileEncrypter = new AesZipFileEncrypter(destPath, encrypter);
/**
* 此方法是修改源碼后添加,用以支持中文文件名
*/
zipFileEncrypter.setEncoding("utf8");
File sFile = new File(srcFile);
/**
* AesZipFileEncrypter提供了重載的添加Entry的方法,其中:
* add(File f, String passwd)
* 方法是將文件直接添加進(jìn)壓縮文件
*
* add(File f, String pathForEntry, String passwd)
* 方法是按指定路徑將文件添加進(jìn)壓縮文件
* pathForEntry - to be used for addition of the file (path within zip file)
*/
doZip(sFile, zipFileEncrypter, "", passwd);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
zipFileEncrypter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 具體壓縮方法,將給定文件添加進(jìn)壓縮文件中,并處理壓縮文件中的路徑
* @param file 給定磁盤文件(是文件直接添加,是目錄遞歸調(diào)用添加)
* @param encrypter AesZipFileEncrypter實(shí)例,用于輸出加密ZIP文件
* @param pathForEntry ZIP文件中的路徑
* @param passwd 壓縮密碼
* @throws IOException
*/
private static void doZip(File file, AesZipFileEncrypter encrypter,
String pathForEntry, String passwd) throws IOException {
if (file.isFile()) {
pathForEntry += file.getName();
encrypter.add(file, pathForEntry, passwd);
return;
}
pathForEntry += file.getName() + File.separator;
for(File subFile : file.listFiles()) {
doZip(subFile, encrypter, pathForEntry, passwd);
}
}
/**
* 使用給定密碼解壓指定壓縮文件到指定目錄
* @param inFile 指定Zip文件
* @param outDir 解壓目錄
* @param passwd 解壓密碼
*/
public static void unzip(String inFile, String outDir, String passwd) {
File outDirectory = new File(outDir);
if (!outDirectory.exists()) {
outDirectory.mkdir();
}
AESDecrypter decrypter = new AESDecrypterBC();
AesZipFileDecrypter zipDecrypter = null;
try {
zipDecrypter = new AesZipFileDecrypter(new File(inFile), decrypter);
AesZipFileDecrypter.charset = "utf-8";
/**
* 得到ZIP文件中所有Entry,但此處好像與JDK里不同,目錄不視為Entry
* 需要?jiǎng)?chuàng)建文件夾,entry.isDirectory()方法同樣不適用,不知道是不是自己使用錯(cuò)誤
* 處理文件夾問題處理可能不太好
*/
ListExtZipEntry entryList = zipDecrypter.getEntryList();
for(ExtZipEntry entry : entryList) {
String eName = entry.getName();
String dir = eName.substring(0, eName.lastIndexOf(File.separator) + 1);
File extractDir = new File(outDir, dir);
if (!extractDir.exists()) {
FileUtils.forceMkdir(extractDir);
}
/**
* 抽出文件
*/
File extractFile = new File(outDir + File.separator + eName);
zipDecrypter.extractEntry(entry, extractFile, passwd);
}
} catch (IOException e) {
e.printStackTrace();
} catch (DataFormatException e) {
e.printStackTrace();
} finally {
try {
zipDecrypter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 測試
* @param args
*/
public static void main(String[] args) {
/**
* 壓縮測試
* 可以傳文件或者目錄
*/
// zip("M:\\ZIP\\test\\bb\\a\\t.txt", "M:\\ZIP\\test\\temp1.zip", "zyh");
// zip("M:\\ZIP\\test\\bb", "M:\\ZIP\\test\\temp2.zip", "zyh");
unzip("M:\\ZIP\\test\\temp2.zip", "M:\\ZIP\\test\\temp", "zyh");
}
}
壓縮多個(gè)文件時(shí),有兩個(gè)方法(第一種沒試):
(1) 預(yù)先把多個(gè)文件壓縮成zip,然后調(diào)用enc.addAll(inZipFile, password);方法將多個(gè)zip文件加進(jìn)來。
(2)針對需要壓縮的文件循環(huán)調(diào)用enc.add(inFile, password);,每次都用相同的密碼。
JCE是java加密擴(kuò)展包,由于美國出口限制規(guī)定,JCE對部分國家是限制出口的,致使其加密長度有所縮減,例如,DES算法因受到軍事出口限制,目前僅提供56位的密鑰長度,而實(shí)際安全要求至少要128位。對于出口限制,SUN公司通過權(quán)限文件做了相應(yīng)限制(local_policy.jar和US_export_policy.jar),而UnlimitedJCEPolicyJDK7就是用來減少相關(guān)限制的相關(guān)文件。