常用加密算法及Java实现
歡迎光臨我的博客查看最新文章: https://river106.cn
1、概述
加密在平時開發中也會經常用到,涉及登錄、支付、接口設計等方面,可能都需要考慮到加密算法,加密算法分對稱加密和非對稱加密,對稱加密使用的密鑰只有一個,發送和接收雙方都使用這個密鑰對數據進行加密和解密,非對稱加密算法,需要兩個密鑰,一個是公鑰 (public key),另一個是私鑰 (private key),如果使用公鑰對數據 進行加密,只有用對應的私鑰才能進行解密。如果使用私鑰對數據 進行加密,只有用對應的公鑰才能進行解密。
?
2、MD5
MD5一般用于對一段信息產生信息摘要即生成數字簽名,以?防止被篡改。無論是多長的輸入,MD5?都會輸出長度為?128bits?的一個串 (通常用?16?進制?表示為?32?個字符)。
java代碼如下:
import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;public class Md5Utils {private static final String UTF8 = "utf-8";/*** 加密** @param plainText 待加密字符串* @return*/public final static String encoder(String plainText)throws NoSuchAlgorithmException, UnsupportedEncodingException {byte[] bytes = plainText.getBytes(UTF8);MessageDigest mdInst = MessageDigest.getInstance("MD5");mdInst.update(bytes);byte[] md = mdInst.digest();StringBuffer sb = new StringBuffer();for (int i = 0; i < md.length; i++) {int val = ((int) md[i]) & 0xff;if (val < 16) {sb.append("0");}sb.append(Integer.toHexString(val));}return sb.toString();}}3、SHA1
SHA1 是和 MD5 一樣流行的 消息摘要算法,然而 SHA1 比 MD5 的 安全性更強。對于長度小于 2 ^ 64 位的消息,SHA1 會產生一個 160 位的 消息摘要。基于 MD5、SHA1 的信息摘要一般而言不可逆 ,可以被應用在檢查 文件完整性 以及 數字簽名 等場景。
java代碼如下:
import java.security.MessageDigest;public final class Sha1Utils {private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};/*** Takes the raw bytes from the digest and formats them correct.* @param bytes the raw bytes from the digest.* @return the formatted bytes.*/private static String getFormattedText(byte[] bytes) {int len = bytes.length;StringBuilder buf = new StringBuilder(len * 2);// 把密文轉換成十六進制的字符串形式for (int j = 0; j < len; j++) {buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);buf.append(HEX_DIGITS[bytes[j] & 0x0f]);}return buf.toString();}public static String encode(String str) {if (str == null) {return null;}try {MessageDigest messageDigest = MessageDigest.getInstance("SHA1");messageDigest.update(str.getBytes());return getFormattedText(messageDigest.digest());} catch (Exception e) {throw new RuntimeException(e);}}}4、RSA
RSA 加密算法是目前比較優秀的公鑰方案。RSA是第一個能同時用于加密和數字簽名的算法,它能夠抵抗到目前為止已知的 所有密碼攻擊,已被 ISO推薦為公鑰數據加密標準。RSA 加密算法 基于一個十分簡單的數論事實:將兩個大 素數 相乘十分容易,但想要對其乘積進行 因式分解 卻極其困難,因此可以將 乘積 公開作為 加密密鑰。
java代碼如下:
import javax.crypto.Cipher; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64;public class RsaUtils {private static final String UTF8 = "UTF-8";/*** 隨機生成密鑰對** @throws NoSuchAlgorithmException*/public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException {// KeyPairGenerator類用于生成公鑰和私鑰對,基于RSA算法生成對象KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");// 初始化密鑰對生成器,密鑰大小為96-1024位keyPairGen.initialize(1024, new SecureRandom());// 生成一個密鑰對,保存在keyPair中KeyPair keyPair = keyPairGen.generateKeyPair();// 得到私鑰RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();// 得到公鑰RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();// 得到公鑰字符串String publicKeyString = new String(Base64.getEncoder().encode(publicKey.getEncoded()));// 得到私鑰字符串String privateKeyString = new String(Base64.getEncoder().encode((privateKey.getEncoded())));return new RsaKeyPair(publicKeyString, privateKeyString);}/*** RSA公鑰加密** @param plainText 加密字符串* @param publicKey 公鑰* @return 密文* @throws Exception*/public static String encrypt(String plainText, String publicKey) throws Exception {//base64編碼的公鑰byte[] decoded = Base64.getDecoder().decode(publicKey.getBytes(UTF8));RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));//RSA加密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, pubKey);byte[] encodeBytes = Base64.getEncoder().encode(cipher.doFinal(plainText.getBytes(UTF8)));return new String(encodeBytes, UTF8);}/*** RSA私鑰解密** @param encryptText 加密字符串* @param privateKey 私鑰* @return 明文* @throws Exception*/public static String decrypt(String encryptText, String privateKey) throws Exception {//64位解碼加密后的字符串byte[] inputByte = Base64.getDecoder().decode(encryptText.getBytes(UTF8));//base64編碼的私鑰byte[] decoded = Base64.getDecoder().decode(privateKey.getBytes(UTF8));RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));//RSA解密Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, priKey);String outStr = new String(cipher.doFinal(inputByte));return outStr;}public static void main(String[] args) throws Exception {// 生成公鑰和私鑰RsaKeyPair rsaKeyPair = generateKeyPair();// 加密字符串String message = "river106";System.out.println("隨機生成的公鑰為:" + rsaKeyPair.getPublicKey());System.out.println("隨機生成的私鑰為:" + rsaKeyPair.getPrivateKey());System.out.println("原始內容: "+message);String encryptText = encrypt(message, rsaKeyPair.getPublicKey());System.out.println("加密后的字符串為:" + encryptText);String messageDe = decrypt(encryptText, rsaKeyPair.getPrivateKey());System.out.println("解密后的字符串為:" + messageDe);}private static class RsaKeyPair {private String publicKey;private String privateKey;public RsaKeyPair() {}public RsaKeyPair(String publicKey, String privateKey) {this.publicKey = publicKey;this.privateKey = privateKey;}public String getPublicKey() {return publicKey;}public void setPublicKey(String publicKey) {this.publicKey = publicKey;}public String getPrivateKey() {return privateKey;}public void setPrivateKey(String privateKey) {this.privateKey = privateKey;}}}
5、DES
DES是對稱的塊加密算法,加解密的過程是可逆的。
DES 加密算法是一種 分組密碼,以 64 位為 分組對數據 加密,它的 密鑰長度 是 56 位,加密解密 用 同一算法。
DES 加密算法是對 密鑰 進行保密,而 公開算法,包括加密和解密算法。這樣,只有掌握了和發送方 相同密鑰 的人才能解讀由 DES加密算法加密的密文數據。因此,破譯 DES 加密算法實際上就是 搜索密鑰的編碼。對于 56 位長度的 密鑰 來說,如果用 窮舉法 來進行搜索的話,其運算次數為 2 ^ 56 次。
java代碼如下:
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.util.Base64;public class DesUtils {private static final String UTF8 = "UTF-8";private static byte[] iv = {1, 2, 3, 4, 5, 6, 7, 8};/*** DES加密* @param plainText 待加密內容* @param encryptKey 加密key* @return* @throws Exception*/public static String encrypt(String plainText, String encryptKey) throws Exception {IvParameterSpec zeroIv = new IvParameterSpec(iv);SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES");Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);byte[] encryptedData = cipher.doFinal(plainText.getBytes(UTF8));return new String(Base64.getEncoder().encode(encryptedData), UTF8);}/*** DES解密* @param encryptedText 已加密內容* @param decryptKey 解密key* @return* @throws Exception*/public static String decrypt(String encryptedText, String decryptKey) throws Exception {IvParameterSpec zeroIv = new IvParameterSpec(iv);SecretKeySpec key = new SecretKeySpec(decryptKey.getBytes(UTF8), "DES");Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);byte decryptedData[] = cipher.doFinal(Base64.getDecoder().decode(encryptedText.getBytes(UTF8)));return new String(decryptedData, UTF8);}}6、AES
AES是對稱的塊加密算法,加解密的過程是可逆的。
AES 加密算法是密碼學中的高級加密標準,該加密算法采用 對稱分組密碼體制,密鑰長度的最少支持為 128 位、 192 位、256 位,分組長度 128 位,算法應易于各種硬件和軟件實現。這種加密算法是美國聯邦政府采用的 區塊加密標準。
AES 本身就是為了取代 DES 的,AES 具有更好的 安全性、效率 和 靈活性。
java代碼如下:
import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.security.SecureRandom;public class AesUtils {/*** 加密** @param content 需要加密的內容* @param password 加密密碼* @return*/public static String encrypt(String content, String password) throws Exception {StringBuilder sb = new StringBuilder();KeyGenerator kgen = KeyGenerator.getInstance("AES");SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");secureRandom.setSeed(password.getBytes());kgen.init(128, secureRandom);SecretKey secretKey = kgen.generateKey();byte[] enCodeFormat = secretKey.getEncoded();SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 創建密碼器Cipher cipher = Cipher.getInstance("AES");byte[] byteContent = content.getBytes("utf-8");// 初始化cipher.init(Cipher.ENCRYPT_MODE, key);byte[] result = cipher.doFinal(byteContent);//將10進制字節數組轉化為16進制字符串for (int i = 0; i < result.length; i++) {String hex = Integer.toHexString(result[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}sb.append(hex.toUpperCase());}return sb.toString();}/*** 解密** @param content 待解密內容* @param password 解密密鑰* @return*/public static String decrypt(String content, String password) throws Exception {//將16進制字符創轉為10進制字節數組byte[] result = new byte[content.length() / 2];for (int i = 0; i < content.length() / 2; i++) {int high = Integer.parseInt(content.substring(i * 2, i * 2 + 1), 16);int low = Integer.parseInt(content.substring(i * 2 + 1, i * 2 + 2), 16);result[i] = (byte) (high * 16 + low);}KeyGenerator kgen = KeyGenerator.getInstance("AES");SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");secureRandom.setSeed(password.getBytes());kgen.init(128, secureRandom);SecretKey secretKey = kgen.generateKey();byte[] enCodeFormat = secretKey.getEncoded();SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 創建密碼器Cipher cipher = Cipher.getInstance("AES");// 初始化cipher.init(Cipher.DECRYPT_MODE, key);byte[] data = cipher.doFinal(result);return new String(data);}}
?
總結
以上是生活随笔為你收集整理的常用加密算法及Java实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WPF界面控件Telerik UI fo
- 下一篇: 排序算法详解(Java实现 + 动画演示