常用加密算法及Java实现

加密在平时开发中也会经常用到 , 涉及登录、支付、接口设计等方面 , 可能都需要考虑到加密算法 , 加密算法分对称加密和非对称加密 , 对称加密使用的密钥只有一个 , 发送和接收双方都使用这个密钥对数据进行加密和解密 , 非对称加密算法 , 需要两个密钥 , 一个是公钥 (public key) , 另一个是私钥 (private key) , 如果使用公钥对数据 进行加密 , 只有用对应的私钥才能进行解密 。如果使用私钥对数据 进行加密 , 只有用对应的公钥才能进行解密 。
 
1、MD5MD5一般用于对一段信息产生信息摘要即生成数字签名 , 以防止被篡改 。无论是多长的输入 , 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();} } 
2、SHA1SHA1 是和 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'};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);}} } 
3、RSARSA 加密算法是目前比较优秀的公钥方案 。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;}} }


推荐阅读