JAVA各種加密與解密方式匯總
一、凱撒加密
在密碼學(xué)中,凱撒加密是一種最簡(jiǎn)單且最廣為人知的加密技術(shù)。它是一種替換加密的技術(shù),明文中的所有字母都在字母表上向后(或向前)按照一個(gè)固定數(shù)目進(jìn)行偏移后被替換成密文。這個(gè)加密方法是以羅馬共和時(shí)期愷撒的名字命名的,當(dāng)年愷撒曾用此方法與其將軍們進(jìn)行聯(lián)系。
public class caesarCipher { public static void main(String[] args) { String show = "ABCDEFGHIJKLMNOPQRSTUVWXYZ~~"; int key = 3; String ciphertext = encryption(show, key, true); System.out.println(ciphertext); String showText = encryption(ciphertext, key, false); System.out.println(showText); } /** * @param text 明文/密文 * @param key 位移 * @param mode 加密/解密 true/false * @return 密文/明文 */ private static String encryption(String text, int key, boolean mode) { char[] chars = text.toCharArray(); StringBuffer sb = new StringBuffer(); for (char aChar : chars) { int a = mode ? aChar + key : aChar - key; char newa = (char) a; sb.append(newa); } return sb.toString(); } }
明文字母表:ABCDEFGHIJKLMNOPQRSTUVWXYZ~~
密文字母表:DEFGHIJKLMNOPQRSTUVWXYZ[\]
注意:當(dāng)字符的ASCII碼 + 偏移量 > 127,密文轉(zhuǎn)化出來會(huì)亂碼,~(波浪號(hào)):126+3=129
二、Base64
Base64是網(wǎng)絡(luò)上最常見的用于傳輸8Bit字節(jié)碼的編碼方式之一,Base64就是一種基于64個(gè)可打印字符來表示二進(jìn)制數(shù)據(jù)的方法。
base64 : A-Z a-z 0-9 + /
Base64要求把每三個(gè)8Bit的字節(jié)轉(zhuǎn)換為四個(gè)6Bit的字節(jié)(3*8 = 4*6 = 24),然后把6Bit再添兩位高位0,組成四個(gè)8Bit的字節(jié),也就是說,轉(zhuǎn)換后的字符串理論上將要比原來的長(zhǎng)1/3。
import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException; import com.sun.org.apache.xml.internal.security.utils.Base64; import java.nio.charset.StandardCharsets; public class base64Demo { public static void main(String[] args) throws Base64DecodingException { //MQ== 一個(gè)字節(jié)補(bǔ)兩個(gè)= System.out.println(Base64.encode("1".getBytes(StandardCharsets.UTF_8))); //MTE= 兩個(gè)字節(jié)補(bǔ)一個(gè)= System.out.println(Base64.encode("11".getBytes(StandardCharsets.UTF_8))); //MTEx System.out.println(Base64.encode("111".getBytes(StandardCharsets.UTF_8))); //解密11 System.out.println(new String(Base64.decode("MTE="))); } }
三、信息摘要算法(MD5 或 SHA)
信息摘要是安全的單向哈希函數(shù),它接收任意大小的數(shù)據(jù),并輸出固定長(zhǎng)度的哈希值。
import com.alibaba.fastjson.JSON; import com.sun.org.apache.xml.internal.security.utils.Base64; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HashMap; //信息摘要是安全的單向哈希函數(shù),它接收任意大小的數(shù)據(jù),并輸出固定長(zhǎng)度的哈希值。 public class DigestDemo { /** * @param input 明文 * @param algorithm 算法 MD5 | sha-1 SHA-256 | * @return 密文 Base64 & Hex */ private static String toHexOrBase64(String input, String algorithm) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance(algorithm); byte[] digest1 = digest.digest(input.getBytes(StandardCharsets.UTF_8)); String base64 = Base64.encode(digest1); StringBuffer haxValue = new StringBuffer(); for (byte b : digest1) { //0xff是16進(jìn)制數(shù),這個(gè)剛好8位都是1的二進(jìn)制數(shù),而且轉(zhuǎn)成int類型的時(shí)候,高位會(huì)補(bǔ)0 int val = ((int) b) & 0xff;//只取得低八位 //在&正數(shù)byte值的話,對(duì)數(shù)值不會(huì)有改變 在&負(fù)數(shù)數(shù)byte值的話,對(duì)數(shù)值前面補(bǔ)位的1會(huì)變成0, if (val < 16) { haxValue.append("0");//位數(shù)不夠,高位補(bǔ)0 } haxValue.append(Integer.toHexString(val)); } HashMap<String, String> DigestMap = new HashMap<>(); DigestMap.put("Base64", base64); DigestMap.put("Hex", String.valueOf(haxValue)); return JSON.toJSONString(DigestMap); } }
加密原文:123456
算法 | Base64 |
MD5 | 4QrcOUm6Wau+VuBX8g+IPg== |
sha-1 | fEqNCco3Yq9h5ZUglD3CZJT4lBs= |
sha-256 | jZae727K08KaOmKSgOaGzww/XVqGr/PKEgIMkjrcbJI= |
算法 | Hex |
MD5 | e10adc3949ba59abbe56e057f20f883e |
sha-1 | 7c4a8d09ca3762af61e59520943dc26494f8941b |
sha-256 | 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 |
四、對(duì)稱加密(Des,Triple Des,AES)
采用單鑰密碼系統(tǒng)的加密方法,同一個(gè)密鑰可以同時(shí)用作信息的加密和解密,這種加密方法稱為對(duì)稱加密,也稱為單密鑰加密。常用的單向加密算法:
- DES(Data Encryption Standard):數(shù)據(jù)加密標(biāo)準(zhǔn),速度較快,適用于加密大量數(shù)據(jù)的場(chǎng)合;
- 3DES(Triple DES):是基于DES,對(duì)一塊數(shù)據(jù)用三個(gè)不同的密鑰進(jìn)行三次加密,強(qiáng)度更高;
- AES(Advanced Encryption Standard):高級(jí)加密標(biāo)準(zhǔn),是下一代的加密算法標(biāo)準(zhǔn),速度快,安全級(jí)別高,支持128、192、256位密鑰的加密;
加密原文:你好世界??!
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; public class desOrAesDemo { public static void main(String[] args) throws Exception { String text = "你好世界??!"; String key = "12345678";//des必須8字節(jié) // 算法/模式/填充 默認(rèn) DES/ECB/PKCS5Padding String transformation = "DES"; String key1 = "1234567812345678";//aes必須16字節(jié) String transformation1 = "AES"; String key2 = "123456781234567812345678";//TripleDES使用24字節(jié)的key String transformation2 = "TripleDes"; String extracted = extracted(text, key, transformation, true); System.out.println("DES加密:" + extracted); String extracted1 = extracted(extracted, key, transformation, false); System.out.println("解密:" + extracted1); String extracted2 = extracted(text, key1, transformation1, true); System.out.println("AES加密:" + extracted2); String extracted3 = extracted(extracted2, key1, transformation1, false); System.out.println("解密:" + extracted3); String extracted4 = extracted(text, key2, transformation2, true); System.out.println("Triple Des加密:" + extracted4); String extracted5 = extracted(extracted, key2, transformation2, false); System.out.println("解密:" + extracted5); } /** * @param text 明文/base64密文 * @param key 密鑰 * @param transformation 轉(zhuǎn)換方式 * @param mode 加密/解密 */ private static String extracted(String text, String key, String transformation, boolean mode) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { Cipher cipher = Cipher.getInstance(transformation); // key 與給定的密鑰內(nèi)容相關(guān)聯(lián)的密鑰算法的名稱 SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), transformation); //Cipher 的操作模式,加密模式:ENCRYPT_MODE、 解密模式:DECRYPT_MODE、包裝模式:WRAP_MODE 或 解包裝:UNWRAP_MODE) cipher.init(mode ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secretKeySpec); byte[] bytes = cipher.doFinal(mode ? text.getBytes(StandardCharsets.UTF_8) : Base64.decode(text)); return mode ? Base64.encode(bytes) : new String(bytes); } }
算法 | 密匙 | 密文 |
DES | 12345678 8位 | j+tPzTH7ttEeK+FrJaLY8OwmOezdN8hF |
AES | 12345678*2 16位 | /+cq03JhyvrTIJyYvWwc2Dc/bFUBNKelKPSANnWgsAw= |
TripleDes | 12345678*3 24位 | j+tPzTH7ttEeK+FrJaLY8OwmOezdN8hF |
五、非對(duì)稱加密
公鑰加密,也叫非對(duì)稱(密鑰)加密(public key encryption),屬于通信科技下的網(wǎng)絡(luò)安全二級(jí)學(xué)科,指的是由對(duì)應(yīng)的一對(duì)唯一性密鑰(即公開密鑰和私有密鑰)組成的加密方法。它解決了密鑰的發(fā)布和管理問題,是商業(yè)密碼的核心。在公鑰加密體制中,沒有公開的是私鑰,公開的是公鑰。常用的算法:
RSA、ElGamal、背包算法、Rabin(Rabin的加密法可以說是RSA方法的特例)、Diffie-Hellman (D-H) 密鑰交換協(xié)議中的公鑰加密算法、Elliptic Curve Cryptography(ECC,橢圓曲線加密算法)。
1.生成公鑰和私鑰文件
目前JDK1.8支持 RSA、DSA、DIFFIEHELLMAN、EC
/** * 生成公鑰和私鑰文件 * @param algorithm 算法 * @param privatePath 私鑰路徑 * @param publicPath 公鑰路徑 */ private static void generateKeyFile(String algorithm, String privatePath, String publicPath) throws NoSuchAlgorithmException, IOException { //返回生成指定算法的 public/private 密鑰對(duì)的 KeyPairGenerator 對(duì)象 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm); //生成一個(gè)密鑰對(duì) KeyPair keyPair = keyPairGenerator.generateKeyPair(); //私鑰 PrivateKey privateKey = keyPair.getPrivate(); //公鑰 PublicKey publicKey = keyPair.getPublic(); byte[] privateKeyEncoded = privateKey.getEncoded(); byte[] publicKeyEncoded = publicKey.getEncoded(); String privateEncodeString = Base64.encode(privateKeyEncoded); String publicEncodeString = Base64.encode(publicKeyEncoded); //需導(dǎo)入commons-io FileUtils.writeStringToFile(new File(privatePath), privateEncodeString, StandardCharsets.UTF_8); FileUtils.writeStringToFile(new File(publicPath), publicEncodeString, StandardCharsets.UTF_8); }
2.使用RSA進(jìn)行加密、解密
package cryptography; import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException; import com.sun.org.apache.xml.internal.security.utils.Base64; import org.apache.commons.io.FileUtils; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; public class RSADemo { public static void main(String[] args) throws Exception { String text = "===你好世界==="; String algorithm = "RSA"; PublicKey publicKey = getPublicKey(algorithm, "rsaKey/publicKey2.txt"); PrivateKey privateKey = getPrivateKey(algorithm, "rsaKey/privateKey2.txt"); String s = RSAEncrypt(text, algorithm, publicKey); String s1 = RSADecrypt(s, algorithm, privateKey); System.out.println(s); System.out.println(s1); //generateKeyFile("DSA","D:\\privateKey2.txt","D:\\publicKey2.txt"); } /** * 獲取公鑰,key * @param algorithm 算法 * @param publicPath 密匙文件路徑 * @return */ private static PublicKey getPublicKey(String algorithm, String publicPath) throws IOException, NoSuchAlgorithmException, Base64DecodingException, InvalidKeySpecException { String publicEncodeString = FileUtils.readFileToString(new File(publicPath), StandardCharsets.UTF_8); //返回轉(zhuǎn)換指定算法的 public/private 關(guān)鍵字的 KeyFactory 對(duì)象。 KeyFactory keyFactory = KeyFactory.getInstance(algorithm); //此類表示根據(jù) ASN.1 類型 SubjectPublicKeyInfo 進(jìn)行編碼的公用密鑰的 ASN.1 編碼 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(publicEncodeString)); return keyFactory.generatePublic(x509EncodedKeySpec); } /** * 獲取私鑰,key * @param algorithm 算法 * @param privatePath 密匙文件路徑 * @return */ private static PrivateKey getPrivateKey(String algorithm, String privatePath) throws IOException, NoSuchAlgorithmException, Base64DecodingException, InvalidKeySpecException { String privateEncodeString = FileUtils.readFileToString(new File(privatePath), StandardCharsets.UTF_8); //返回轉(zhuǎn)換指定算法的 public/private 關(guān)鍵字的 KeyFactory 對(duì)象。 KeyFactory keyFactory = KeyFactory.getInstance(algorithm); //創(chuàng)建私鑰key的規(guī)則 此類表示按照 ASN.1 類型 PrivateKeyInfo 進(jìn)行編碼的專用密鑰的 ASN.1 編碼 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decode(privateEncodeString)); //私鑰對(duì)象 return keyFactory.generatePrivate(pkcs8EncodedKeySpec); } /** * 加密 * @param text 明文 * @param algorithm 算法 * @param key 私鑰/密鑰 * @return 密文 */ private static String RSAEncrypt(String text, String algorithm, Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException { Cipher cipher = Cipher.getInstance(algorithm); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] bytes = cipher.doFinal(text.getBytes(StandardCharsets.UTF_8)); return Base64.encode(bytes); } /** * 解密 * @param extracted 密文 * @param algorithm 算法 * @param key 密鑰/私鑰 * @return String 明文 */ private static String RSADecrypt(String extracted, String algorithm, Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, Base64DecodingException, NoSuchProviderException { Cipher cipher = Cipher.getInstance(algorithm); cipher.init(Cipher.DECRYPT_MODE, key); byte[] bytes1 = cipher.doFinal(Base64.decode(extracted)); return new String(bytes1); } /** * 生成公鑰和私鑰文件 * @param algorithm 算法 * @param privatePath 私鑰路徑 * @param publicPath 公鑰路徑 */ private static void generateKeyFile(String algorithm, String privatePath, String publicPath) throws NoSuchAlgorithmException, IOException { //返回生成指定算法的 public/private 密鑰對(duì)的 KeyPairGenerator 對(duì)象 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm); //生成一個(gè)密鑰對(duì) KeyPair keyPair = keyPairGenerator.generateKeyPair(); //私鑰 PrivateKey privateKey = keyPair.getPrivate(); //公鑰 PublicKey publicKey = keyPair.getPublic(); byte[] privateKeyEncoded = privateKey.getEncoded(); byte[] publicKeyEncoded = publicKey.getEncoded(); String privateEncodeString = Base64.encode(privateKeyEncoded); String publicEncodeString = Base64.encode(publicKeyEncoded); //需導(dǎo)入commons-io FileUtils.writeStringToFile(new File(privatePath), privateEncodeString, StandardCharsets.UTF_8); FileUtils.writeStringToFile(new File(publicPath), publicEncodeString, StandardCharsets.UTF_8); } }
密文(明文:===你好世界===)
ZBadyYCIck2iYV8RtsY35T1GbaYt9aLS51dcws5H4IcrOH+i6/8AIEdgtwJO3p1ccqKP6XTwQAWm
ceJ7kpsk76nvFD8Hg2pLYzH2oEE+oy07bLBdBiE+zVFkP+0DL+nrsHO4elQxc9BSslj5wGLQqbb1
Mxh9Tcpf5zJEOxdBZvE=
六、查看系統(tǒng)支持的算法
public static void main(String[] args) throws Exception { System.out.println("列出加密服務(wù)提供者:"); Provider[] pro=Security.getProviders(); for(Provider p:pro){ System.out.println("Provider:"+p.getName()+" - version:"+p.getVersion()); System.out.println(p.getInfo()); } System.out.println("======="); System.out.println("列出系統(tǒng)支持的消息摘要算法:"); for(String s:Security.getAlgorithms("MessageDigest")){ System.out.println(s); } System.out.println("======="); System.out.println("列出系統(tǒng)支持的生成公鑰和私鑰對(duì)的算法:"); for(String s:Security.getAlgorithms("KeyPairGenerator")){ System.out.println(s); } }
其他加密算法可以使用 Bouncy Castle Crypto包
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.70</version> </dependency>
到此這篇關(guān)于JAVA各種加密與解密方式匯總的文章就介紹到這了,更多相關(guān)JAVA 加密解密內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中if...else語句使用的學(xué)習(xí)教程
這篇文章主要介紹了Java中if...else語句使用的學(xué)習(xí)教程,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-11-11SpringBoot之整合MyBatis實(shí)現(xiàn)CRUD方式
這篇文章主要介紹了SpringBoot之整合MyBatis實(shí)現(xiàn)CRUD方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08Sentinel的熔斷降級(jí)、資源規(guī)則詳解與實(shí)例
這篇文章主要介紹了Sentinel的熔斷降級(jí)、資源規(guī)則詳解與實(shí)例,Sentinel是阿里巴巴開源的一款流量控制和熔斷降級(jí)的框架,它主要用于保護(hù)分布式系統(tǒng)中的服務(wù)穩(wěn)定性,Sentinel通過對(duì)服務(wù)進(jìn)行流量控制和熔斷降級(jí),可以有效地保護(hù)系統(tǒng)的穩(wěn)定性,需要的朋友可以參考下2023-09-09IDEA生成項(xiàng)目后出現(xiàn)的iml和idea文件問題
這篇文章主要介紹了IDEA生成項(xiàng)目后出現(xiàn)的iml和idea文件問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08Java+Freemarker實(shí)現(xiàn)根據(jù)XML模板文件生成Word文檔
這篇文章主要為大家詳細(xì)介紹了Java如何使用Freemarker實(shí)現(xiàn)根據(jù)XML模板文件生成Word文檔,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下2023-11-11MyBatis中的循環(huán)插入insert foreach問題
這篇文章主要介紹了MyBatis中的循環(huán)插入insert foreach問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11SpringBoot Logback日志記錄到數(shù)據(jù)庫的實(shí)現(xiàn)方法
這篇文章主要介紹了SpringBoot Logback日志記錄到數(shù)據(jù)庫的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11詳解Spring Cloud微服務(wù)架構(gòu)下的WebSocket解決方案
這篇文章主要介紹了詳解Spring Cloud微服務(wù)架構(gòu)下的WebSocket解決方案,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12