本篇内容简要介绍 BASE64、MD5、SHA、HMAC、DES、AES、PBE、RSA、DH、DSA几种加密算法。

  • BASE64:严格地说,属于编码格式,而非加密算法
    BASE的加密解密是双向的,可以求反解.
    BASEEncoder和BASEDecoder是非官方JDK实现类。虽然可以在JDK里能找到并使用,但是在API里查不到。JRE 中 sun 和 com.sun 开头包的类都是未被文档化的,他们属于 java, javax 类库的基础,其中的实现大多数与底层平台有关,一般来说是不推荐使用的。BASE 严格地说,属于编码格式,而非加密算法主要就是BASEEncoder、BASEDecoder两个类,我们只需要知道使用对应的方法即可。另,BASE加密后产生的字节位数是的倍数,如果不够位数以=符号填充。BASE按照RFC的定义,Base被定义为:Base内容传送编码被设计用来把任意序列的位字节描述为一种不易被人直接识别的形式。常见于邮件、http加密,截取http信息,你就会发现登录操作的用户名、密码字段通过BASE加密的。
    Java代码示例:
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;public class BASE {/*** BASE解密* @param key* @return* @throws Exception*/public static byte[] decryptBASE(String key) throws Exception {return (new BASE64Decoder()).decodeBuffer(key);}/*** BASE加密* @param key* @return* @throws Exception*/public static String encryptBASE(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}public static void main(String[] args) {String str = "123456";try {String result = BASE.encryptBASE(str.getBytes());System.out.println("加密数据>>>>:" + result);byte[] result1 = BASE.decryptBASE(result);String str1 = new String(result1);System.out.println("解密数据>>>>:" + str1);} catch (Exception e) {e.printStackTrace();}}
}

1.单向加密

该算法在加密过程中不需要使用密钥,输入明文后由系统直接经过加密算法处理成密文,密文无法解密。只有重新输入明文,并经过同样的加密算法处理,得到相同的密文并被系统重新识别后,才能真正解密。常见的有:

  • MD5(Message Digest algorithm 5,信息摘要算法)广泛用于加密和解密技术,常用于文件校验。不管文件多大,经过MD5后都能生成唯一的MD5值。好比现在的ISO校验,都 是MD5校验。怎么用?当然是把ISO经过MD5后产生MD5的值。一般下载linux-ISO的朋友都见过下载链接旁边放着MD5的串。就是用来验证文 件是否一致的。
    Java代码示例:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.security.MessageDigest;public class MD5Utils {private static final Logger logger = LoggerFactory.getLogger(MD5Utils.class);private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};public static String md5toHex(String src) {try {MessageDigest md5 = MessageDigest.getInstance("MD5");byte[] bytes = md5.digest(src.getBytes("UTF-8"));return bytesToHex(bytes);} catch (Exception e) {logger.error("md5toHex occurs exception!", e);return null;}}public static String bytesToHex(byte[] byteArray) {char[] resultCharArray = new char[byteArray.length * 2];int index = 0;for (byte b : byteArray) {resultCharArray[index++] = HEX_DIGITS[b >>> 4 & 0xf];resultCharArray[index++] = HEX_DIGITS[b & 0xf];}return new String(resultCharArray);}}
  • SHA(Secure Hash Algorithm,安全散列算法):数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域。虽然,SHA与MD5通过碰撞法都被破解了,但是SHA仍然是公认的安全加密算法,较之MD5更为安全
    Java代码示例:
//单向加密package com.cn.SHATest;import java.math.BigInteger;import java.security.MessageDigest;public class SHA {public static final String KEY_SHA = "SHA";public static String getResult(String inputStr){BigInteger sha =null;System.out.println("加密前的数据>>>:"+inputStr);byte[] inputData = inputStr.getBytes();try {MessageDigest messageDigest = MessageDigest.getInstance(KEY_SHA);messageDigest.update(inputData);sha = new BigInteger(messageDigest.digest());System.out.println("SHA加密后>>>>>:" + sha.toString());} catch (Exception e) {e.printStackTrace();}return sha.toString();}public static void main(String args[]){try {String inputStr = "简单加密";getResult(inputStr);} catch (Exception e) {e.printStackTrace();}}
  • HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。
    Java代码示例:
//单向加密package com.cn.HMACTest;import javax.crypto.KeyGenerator;import javax.crypto.Mac;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import com.cn.comm.Tools;/*** 基础加密组件*/public abstract class HMAC {public static final String KEY_MAC = "HmacMD";/*** 初始化HMAC密钥** @return* @throws Exception*/public static String initMacKey() throws Exception {KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);SecretKey secretKey = keyGenerator.generateKey();return BASE.encryptBASE(secretKey.getEncoded());}/*** HMAC加密 :主要方法** @param data* @param key* @return* @throws Exception*/public static String encryptHMAC(byte[] data, String key) throws Exception {SecretKey secretKey = new SecretKeySpec(BASE.decryptBASE(key), KEY_MAC);Mac mac = Mac.getInstance(secretKey.getAlgorithm());mac.init(secretKey);return new String(mac.doFinal(data));}public static String getResult(String inputStr){String path=Tools.getClassPath();String fileSource=path+"/file/HMAC_key.txt";System.out.println("加密前的数据>>>>>:"+inputStr);String result=null;try {byte[] inputData = inputStr.getBytes();String key = HMAC.initMacKey(); /*产生密钥*/System.out.println("Mac密钥>>>>>:" + key);/*将密钥写文件*/Tools.WriteMyFile(fileSource,key);result= HMAC.encryptHMAC(inputData, key);System.out.println("HMAC加密后>>>>:" + result);} catch (Exception e) {e.printStackTrace();}return result.toString();}public static String getResult(String inputStr){System.out.println("加密前的数据>>>>:"+inputStr);String path=Tools.getClassPath();String fileSource=path+"/file/HMAC_key.txt";String key=null;;try {/*将密钥从文件中读取*/key=Tools.ReadMyFile(fileSource);System.out.println("getResult密钥>>>>:" + key);} catch (Exception e) {e.printStackTrace();}String result=null;try {byte[] inputData = inputStr.getBytes();/*对数据进行加密*/result= HMAC.encryptHMAC(inputData, key);System.out.println("HMAC加密后>>>>:" + result);} catch (Exception e) {e.printStackTrace();}return result.toString();}public static void main(String args[]){try {String inputStr = "123456";/*使用同一密钥:对数据进行加密:查看两次加密的结果是否一样*/getResult(inputStr);getResult(inputStr);} catch (Exception e) {e.printStackTrace();}}}

2.对称加密

对称加密算法 是应用较早的加密算法,又称为 共享密钥加密算法。在 对称加密算法 中,使用的密钥只有一个,发送 和 接收 双方都使用这个密钥对数据进行 加密 和 解密。这就要求加密和解密方事先都必须知道加密的密钥。

  • DES(Data Encryption Standard,数据加密算法):DES-Data Encryption Standard,即数据加密算法。是IBM公司于1975年研究成功并公开发表的。DES算法的入口参数有三个:Key、Data、Mode。其中 Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密 或解密。DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位。
    Java代码示例:
    Coder类,以下代码都继承到这个类

import java.security.MessageDigest;import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;/*** 基础加密组件*/
public abstract class Coder {public static final String KEY_SHA = "SHA";public static final String KEY_MD5 = "MD5";/*** MAC算法可选以下多种算法* * <pre>* HmacMD5 * HmacSHA1 * HmacSHA256 * HmacSHA384 * HmacSHA512* </pre>*/public static final String KEY_MAC = "HmacMD5";/*** BASE64解密* * @param key* @return* @throws Exception*/public static byte[] decryptBASE64(String key) throws Exception {return (new BASE64Decoder()).decodeBuffer(key);}/*** 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);}
}

DESCoder类:

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.Key;
import java.security.SecureRandom;public abstract class DESCoder extends Coder{public static final String ALGORITHM = "DES";/*** 转换密钥<br>* * @param key* @return* @throws Exception*/private static Key toKey(byte[] key) throws Exception {DESKeySpec dks = new DESKeySpec(key);SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);SecretKey secretKey = keyFactory.generateSecret(dks);// 当使用其他对称加密算法时,如AES、Blowfish等算法时,用下述代码替换上述三行代码// SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);return secretKey;}/*** 解密* * @param data* @param key* @return* @throws Exception*/public static byte[] decrypt(byte[] data, String key) throws Exception {Key k = toKey(decryptBASE64(key));Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, k);return cipher.doFinal(data);}/*** 加密* * @param data* @param key* @return* @throws Exception*/public static byte[] encrypt(byte[] data, String key) throws Exception {Key k = toKey(decryptBASE64(key));Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, k);return cipher.doFinal(data);}/*** 生成密钥* * @return* @throws Exception*/public static String initKey() throws Exception {return initKey(null);}/*** 生成密钥* * @param seed* @return* @throws Exception*/public static String initKey(String seed) throws Exception {SecureRandom secureRandom = null;if (seed != null) {secureRandom = new SecureRandom(decryptBASE64(seed));} else {secureRandom = new SecureRandom();}KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);kg.init(secureRandom);SecretKey secretKey = kg.generateKey();return encryptBASE64(secretKey.getEncoded());}public static void test() throws Exception {String inputStr = "DES";String key = DESCoder.initKey();System.err.println("原文:\t" + inputStr);System.err.println("密钥:\t" + key);byte[] inputData = inputStr.getBytes();inputData = DESCoder.encrypt(inputData, key);System.err.println("加密后:\t" + encryptBASE64(inputData));byte[] outputData = DESCoder.decrypt(inputData, key);String outputStr = new String(outputData);System.err.println("解密后:\t" + outputStr);}public static void main(String[] args) throws Exception {test();}
}
  • AES(Advanced Encryption Standard,高级加密算法):高级数据加密标准(Advanced Encryption Standard),简称AES,由美国政府于1997年开始公开征集的新的数据加密标准算法。经过三轮筛选,美国政府最终于2000年10月2日正式宣布选中密码学家Joan Daemen和Vincent Rijmen提出的RINJDAEL算法作为AES。
    Java代码示例:
public class AESTest {/**
* AES加密字符串
*  * @param content
*      需要被加密的字符串
* @param password
*      加密需要的密码
* @return 密文*/public static byte[] encrypt(String content, String password) {try {// 创建AES的Key生产者KeyGenerator kgen = KeyGenerator.getInstance("AES");// 利用用户密码作为随机数初始化出128位的key生产者kgen.init(128, new SecureRandom(password.getBytes()));//加密没关系,SecureRandom是生成安全随机数序列,password.getBytes()是种子,只要种子相同,序列就一样,所以解密只要有password就行SecretKey secretKey = kgen.generateKey();// 根据用户密码,生成一个密钥// 返回基本编码格式的密钥,如果此密钥不支持编码,则返回null。byte[] enCodeFormat = secretKey.getEncoded();// 转换为AES专用密钥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);return result;} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}return null;}/**
* 解密AES加密过的字符串
*  * @param content
*      AES加密过过的内容
* @param password
*      加密时的密码
* @return 明文*/public static byte[] decrypt(byte[] content, String password) {try {// 创建AES的Key生产者KeyGenerator kgen = KeyGenerator.getInstance("AES");kgen.init(128, new SecureRandom(password.getBytes()));// 根据用户密码,生成一个密钥SecretKey secretKey = kgen.generateKey();// 返回基本编码格式的密钥byte[] enCodeFormat = secretKey.getEncoded();// 转换为AES专用密钥SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 创建密码器Cipher cipher = Cipher.getInstance("AES");// 初始化为解密模式的密码器cipher.init(Cipher.DECRYPT_MODE, key);byte[] result = cipher.doFinal(content);// 明文return result;} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}return null;}/**将二进制转换成16进制
* @param buf
* @return*/public static String parseByte2HexStr(byte buf[]) {StringBuffer sb = new StringBuffer();for (int i = 0; i < buf.length; i++) {String hex = Integer.toHexString(buf[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}sb.append(hex.toUpperCase());}return sb.toString();}/**将16进制转换为二进制
* @param hexStr
* @return*/public static byte[] parseHexStr2Byte(String hexStr) {if (hexStr.length() < 1)return null;byte[] result = new byte[hexStr.length()/2];for (int i = 0;i< hexStr.length()/2; i++) {int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);result[i] = (byte) (high * 16 + low);}return result;}public static void main(String[] args) {String content = "美女,一起共进晚餐么?";String password = "123";//密码就是keySystem.out.println("加密之前:" + content);// 加密byte[] encrypt = AesTest.encrypt(content, password);System.out.println("加密后的内容:" + new String(encrypt));//如果想要加密内容不显示乱码,可以先将密文转换为16进制String hexStrResult = parseByte2HexStr(encrypt);System.out.println("16进制的密文:" + hexStrResult);//如果的到的是16进制密文,别忘了先转为2进制再解密byte[] twoStrResult = parseHexStr2Byte(hexStrResult);// 解密byte[] decrypt = AesTest.decrypt(encrypt, password);System.out.println("解密后的内容:" + new String(decrypt));}
}
  • PBE——Password-based encryption(基于密码加密)。其特点在于口令由用户自己掌管,不借助任何物理媒体;采用随机数(这里我们叫做盐)杂凑多重加密等方法保证数据的安全性。是一种简便的加密方式。
    Java代码示例:
import sun.misc.BASE64Encoder;import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.security.Key;
import java.util.Random;public abstract class PBECoder extends Coder {/**
* 支持以下任意一种算法
*
* <pre>
* PBEWithMD5AndDES
* PBEWithMD5AndTripleDES
* PBEWithSHA1AndDESede
* PBEWithSHA1AndRC2_40
* </pre>*/public static final String ALGORITHM = "PBEWITHMD5andDES";/**
* 盐初始化
*
* @return
* @throws Exception*/public static byte[] initSalt() throws Exception {byte[] salt = new byte[8];Random random = new Random();random.nextBytes(salt);return salt;}/**
* 转换密钥<br>
*
* @param password
* @return
* @throws Exception*/private static Key toKey(String password) throws Exception {PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);SecretKey secretKey = keyFactory.generateSecret(keySpec);return secretKey;}/**
* 加密
*
* @param data 数据
* @param password 密码
* @param salt 盐
* @return
* @throws Exception*/public static byte[] encrypt(byte[] data, String password, byte[] salt)throws Exception {Key key = toKey(password);PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);return cipher.doFinal(data);}/**
* 解密
*
* @param data 数据
* @param password 密码
* @param salt 盐
* @return
* @throws Exception*/public static byte[] decrypt(byte[] data, String password, byte[] salt)throws Exception {Key key = toKey(password);PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);Cipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);return cipher.doFinal(data);}public static void test() throws Exception {String inputStr = "abc";System.err.println("原文: " + inputStr);byte[] input = inputStr.getBytes();String pwd = "efg";System.err.println("密码: " + pwd);byte[] salt = PBECoder.initSalt();byte[] data = PBECoder.encrypt(input, pwd, salt);System.err.println("加密后: " + PBECoder.encryptBASE64(data));byte[] output = PBECoder.decrypt(data, pwd, salt);String outputStr = new String(output);System.err.println("解密后: " + outputStr);}public static void main(String[] args) throws Exception {test();}
}

3.非对称加密

非对称加密算法,又称为 公开密钥加密算法。它需要两个密钥,一个称为 公开密钥 (public key),即 公钥,另一个称为 私有密钥 (private key),即 私钥。

  • RSA(算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman),这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。
    这种加密算法的特点主要是密钥的变化,我们知道DES只有一个密钥。相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥 匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输工程中不被修改。
    Java代码示例:
    RSACoder类:
package com.gomefinance.united.sale.activity.biz.service;import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;
import java.util.Map;import javax.crypto.Cipher;
/**
*RSA安全编码组件
*/
public abstract class RSACoder extends Coder {public static final String KEY_ALGORITHM = "RSA";public static final String SIGNATURE_ALGORITHM = "MD5withRSA";private static final String PUBLIC_KEY = "RSAPublicKey";private static final String PRIVATE_KEY = "RSAPrivateKey";/*** 用私钥对信息生成数字签名* * @param data*      加密数据* @param privateKey*      私钥* * @return* @throws Exception*/public static String sign(byte[] data, String privateKey) throws Exception {// 解密由base64编码的私钥byte[] keyBytes = decryptBASE64(privateKey);// 构造PKCS8EncodedKeySpec对象PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);// KEY_ALGORITHM 指定的加密算法KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 取私钥匙对象PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);// 用私钥对信息生成数字签名Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);signature.initSign(priKey);signature.update(data);return encryptBASE64(signature.sign());}/*** 校验数字签名* * @param data*      加密数据* @param publicKey*      公钥* @param sign*      数字签名* * @return 校验成功返回true 失败返回false* @throws Exception* */public static boolean verify(byte[] data, String publicKey, String sign)throws Exception {// 解密由base64编码的公钥byte[] keyBytes = decryptBASE64(publicKey);// 构造X509EncodedKeySpec对象X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);// KEY_ALGORITHM 指定的加密算法KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 取公钥匙对象PublicKey pubKey = keyFactory.generatePublic(keySpec);Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);signature.initVerify(pubKey);signature.update(data);// 验证签名是否正常return signature.verify(decryptBASE64(sign));}/*** 解密<br>* 用私钥解密* * @param data* @param key* @return* @throws Exception*/public static byte[] decryptByPrivateKey(byte[] data, String key)throws Exception {// 对密钥解密byte[] keyBytes = decryptBASE64(key);// 取得私钥PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);// 对数据解密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);}/*** 解密<br>* 用私钥解密* * @param data* @param key* @return* @throws Exception*/public static byte[] decryptByPublicKey(byte[] data, String key)throws Exception {// 对密钥解密byte[] keyBytes = decryptBASE64(key);// 取得公钥X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key publicKey = keyFactory.generatePublic(x509KeySpec);// 对数据解密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, publicKey);return cipher.doFinal(data);}/*** 加密<br>* 用公钥加密* * @param data* @param key* @return* @throws Exception*/public static byte[] encryptByPublicKey(byte[] data, String key)throws Exception {// 对公钥解密byte[] keyBytes = decryptBASE64(key);// 取得公钥X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key publicKey = keyFactory.generatePublic(x509KeySpec);// 对数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicKey);return cipher.doFinal(data);}/*** 加密<br>* 用私钥加密* * @param data* @param key* @return* @throws Exception*/public static byte[] encryptByPrivateKey(byte[] data, String key)throws Exception {// 对密钥解密byte[] keyBytes = decryptBASE64(key);// 取得私钥PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);// 对数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, privateKey);return cipher.doFinal(data);}/*** 取得私钥* * @param keyMap* @return* @throws Exception*/public static String getPrivateKey(Map<String, Object> keyMap)throws Exception {Key key = (Key) keyMap.get(PRIVATE_KEY);return encryptBASE64(key.getEncoded());}/*** 取得公钥* * @param keyMap* @return* @throws Exception*/public static String getPublicKey(Map<String, Object> keyMap)throws Exception {Key key = (Key) keyMap.get(PUBLIC_KEY);return encryptBASE64(key.getEncoded());}/*** 初始化密钥* * @return* @throws Exception*/public static Map<String, Object> initKey() throws Exception {KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);keyPairGen.initialize(1024);KeyPair keyPair = keyPairGen.generateKeyPair();// 公钥RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();// 私钥RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();Map<String, Object> keyMap = new HashMap<String, Object>(2);keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;}
}

RSACoderTest类:

package com.gomefinance.united.sale.activity.biz.service;import java.util.Map;/*** RSA测试类*/
public class RSACoderTest {private static String publicKey;private static String privateKey;static {Map<String, Object> keyMap = null;try {keyMap = RSACoder.initKey();publicKey = RSACoder.getPublicKey(keyMap);privateKey = RSACoder.getPrivateKey(keyMap);System.err.println("公钥: \n\r" + publicKey);System.err.println("私钥: \n\r" + privateKey);} catch (Exception e) {e.printStackTrace();}}public static void test() throws Exception {System.err.println("公钥加密——私钥解密");String inputStr = "abc";byte[] data = inputStr.getBytes();byte[] encodedData = RSACoder.encryptByPublicKey(data, publicKey);byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData,privateKey);String outputStr = new String(decodedData);System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);}public static void testSign() throws Exception {System.err.println("私钥加密——公钥解密");String inputStr = "sign";byte[] data = inputStr.getBytes();byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);byte[] decodedData = RSACoder.decryptByPublicKey(encodedData, publicKey);String outputStr = new String(decodedData);System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);System.err.println("私钥签名——公钥验证签名");// 产生签名String sign = RSACoder.sign(encodedData, privateKey);System.err.println("签名:\r" + sign);// 验证签名boolean status = RSACoder.verify(encodedData, publicKey, sign);System.err.println("状态:\r" + status);}public static void main(String[] args) throws Exception {test();testSign();}}
  • DH(Diffie- Hellman算法(D-H算法):密钥一致协议。是由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想。简单的说就是允许两名用 户在公开媒体上交换信息以生成"一致"的、可以共享的密钥。换句话说,就是由甲方产出一对密钥(公钥、私钥),乙方依照甲方公钥产生乙方密钥对(公钥、私 钥)。以此为基线,作为数据传输保密基础,同时双方使用同一种对称加密算法构建本地密钥(SecretKey)对数据加密。这样,在互通了本地密钥 (SecretKey)算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公钥和自己的私钥对数据解密。不单 单是甲乙双方两方,可以扩展为多方共享数据通讯,这样就完成了网络交互数据的安全通讯!该算法源于中国的同余定理——中国馀数定理。
    Java代码示例:
    DHCoder类:
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;/*** DH安全编码组件*/
public abstract class DHCoder extends Coder {public static final String ALGORITHM = "DH";/*** 默认密钥字节数* * <pre>* DH* Default Keysize 1024  * Keysize must be a multiple of 64, ranging from 512 to 1024 (inclusive).* </pre>*/private static final int KEY_SIZE = 1024;/*** DH加密下需要一种对称加密算法对数据加密,这里我们使用DES,也可以使用其他对称加密算法。*/public static final String SECRET_ALGORITHM = "DES";private static final String PUBLIC_KEY = "DHPublicKey";private static final String PRIVATE_KEY = "DHPrivateKey";/*** 初始化甲方密钥* * @return* @throws Exception*/public static Map<String, Object> initKey() throws Exception {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);keyPairGenerator.initialize(KEY_SIZE);KeyPair keyPair = keyPairGenerator.generateKeyPair();// 甲方公钥DHPublicKey publicKey = (DHPublicKey) keyPair.getPublic();// 甲方私钥DHPrivateKey privateKey = (DHPrivateKey) keyPair.getPrivate();Map<String, Object> keyMap = new HashMap<String, Object>(2);keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;}/*** 初始化乙方密钥* * @param key*      甲方公钥* @return* @throws Exception*/public static Map<String, Object> initKey(String key) throws Exception {// 解析甲方公钥byte[] keyBytes = decryptBASE64(key);X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);// 由甲方公钥构建乙方密钥DHParameterSpec dhParamSpec = ((DHPublicKey) pubKey).getParams();KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyFactory.getAlgorithm());keyPairGenerator.initialize(dhParamSpec);KeyPair keyPair = keyPairGenerator.generateKeyPair();// 乙方公钥DHPublicKey publicKey = (DHPublicKey) keyPair.getPublic();// 乙方私钥DHPrivateKey privateKey = (DHPrivateKey) keyPair.getPrivate();Map<String, Object> keyMap = new HashMap<String, Object>(2);keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;}/*** 加密<br>* * @param data*      待加密数据* @param publicKey*      甲方公钥* @param privateKey*      乙方私钥* @return* @throws Exception*/public static byte[] encrypt(byte[] data, String publicKey,String privateKey) throws Exception {// 生成本地密钥SecretKey secretKey = getSecretKey(publicKey, privateKey);// 数据加密Cipher cipher = Cipher.getInstance(secretKey.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, secretKey);return cipher.doFinal(data);}/*** 解密<br>* * @param data*      待解密数据* @param publicKey*      乙方公钥* @param privateKey*      乙方私钥* @return* @throws Exception*/public static byte[] decrypt(byte[] data, String publicKey,String privateKey) throws Exception {// 生成本地密钥SecretKey secretKey = getSecretKey(publicKey, privateKey);// 数据解密Cipher cipher = Cipher.getInstance(secretKey.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, secretKey);return cipher.doFinal(data);}/*** 构建密钥* * @param publicKey*      公钥* @param privateKey*      私钥* @return* @throws Exception*/private static SecretKey getSecretKey(String publicKey, String privateKey)throws Exception {// 初始化公钥byte[] pubKeyBytes = decryptBASE64(publicKey);KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKeyBytes);PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);// 初始化私钥byte[] priKeyBytes = decryptBASE64(privateKey);PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKeyBytes);Key priKey = keyFactory.generatePrivate(pkcs8KeySpec);KeyAgreement keyAgree = KeyAgreement.getInstance(keyFactory.getAlgorithm());keyAgree.init(priKey);keyAgree.doPhase(pubKey, true);// 生成本地密钥SecretKey secretKey = keyAgree.generateSecret(SECRET_ALGORITHM);return secretKey;}/*** 取得私钥* * @param keyMap* @return* @throws Exception*/public static String getPrivateKey(Map<String, Object> keyMap)throws Exception {Key key = (Key) keyMap.get(PRIVATE_KEY);return encryptBASE64(key.getEncoded());}/*** 取得公钥* * @param keyMap* @return* @throws Exception*/public static String getPublicKey(Map<String, Object> keyMap)throws Exception {Key key = (Key) keyMap.get(PUBLIC_KEY);return encryptBASE64(key.getEncoded());}
}

DHCoderTest类:

package com.gomefinance.united.sale.activity.biz.service;import java.util.Map;/*** DHCoder测试类*/
public class DHCoderTest {public static void test() throws Exception {// 生成甲方密钥对儿Map<String, Object> aKeyMap = DHCoder.initKey();String aPublicKey = DHCoder.getPublicKey(aKeyMap);String aPrivateKey = DHCoder.getPrivateKey(aKeyMap);System.err.println("甲方公钥:\r" + aPublicKey);System.err.println("甲方私钥:\r" + aPrivateKey);// 由甲方公钥产生本地密钥对儿Map<String, Object> bKeyMap = DHCoder.initKey(aPublicKey);String bPublicKey = DHCoder.getPublicKey(bKeyMap);String bPrivateKey = DHCoder.getPrivateKey(bKeyMap);System.err.println("乙方公钥:\r" + bPublicKey);System.err.println("乙方私钥:\r" + bPrivateKey);String aInput = "abc ";System.err.println("原文: " + aInput);// 由甲方公钥,乙方私钥构建密文byte[] aCode = DHCoder.encrypt(aInput.getBytes(), aPublicKey,bPrivateKey);// 由乙方公钥,甲方私钥解密byte[] aDecode = DHCoder.decrypt(aCode, bPublicKey, aPrivateKey);String aOutput = (new String(aDecode));System.err.println("解密: " + aOutput);System.err.println(" ===============反过来加密解密================== ");String bInput = "def ";System.err.println("原文: " + bInput);// 由乙方公钥,甲方私钥构建密文byte[] bCode = DHCoder.encrypt(bInput.getBytes(), bPublicKey,aPrivateKey);// 由甲方公钥,乙方私钥解密byte[] bDecode = DHCoder.decrypt(bCode, aPublicKey, bPrivateKey);String bOutput = (new String(bDecode));System.err.println("解密: " + bOutput);}public static void main(String[] args) throws Exception {test();}}
  • DSA-Digital Signature Algorithm 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签 名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级!
    java代码示例:
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;/**
* DSA安全编码组件
*/
public abstract class DSACoder extends Coder {public static final String ALGORITHM = "DSA";/*** 默认密钥字节数* * <pre>* DSA * Default Keysize 1024  * Keysize must be a multiple of 64, ranging from 512 to 1024 (inclusive).* </pre>*/private static final int KEY_SIZE = 1024;/*** 默认种子*/private static final String DEFAULT_SEED = "0f22507a10bbddd07d8a3082122966e3";private static final String PUBLIC_KEY = "DSAPublicKey";private static final String PRIVATE_KEY = "DSAPrivateKey";/*** 用私钥对信息生成数字签名* * @param data*      加密数据* @param privateKey*      私钥* * @return* @throws Exception*/public static String sign(byte[] data, String privateKey) throws Exception {// 解密由base64编码的私钥byte[] keyBytes = decryptBASE64(privateKey);// 构造PKCS8EncodedKeySpec对象PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);// KEY_ALGORITHM 指定的加密算法KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);// 取私钥匙对象PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);// 用私钥对信息生成数字签名Signature signature = Signature.getInstance(keyFactory.getAlgorithm());signature.initSign(priKey);signature.update(data);return encryptBASE64(signature.sign());}/*** 校验数字签名* * @param data*      加密数据* @param publicKey*      公钥* @param sign*      数字签名* * @return 校验成功返回true 失败返回false* @throws Exception* */public static boolean verify(byte[] data, String publicKey, String sign)throws Exception {// 解密由base64编码的公钥byte[] keyBytes = decryptBASE64(publicKey);// 构造X509EncodedKeySpec对象X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);// ALGORITHM 指定的加密算法KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);// 取公钥匙对象PublicKey pubKey = keyFactory.generatePublic(keySpec);Signature signature = Signature.getInstance(keyFactory.getAlgorithm());signature.initVerify(pubKey);signature.update(data);// 验证签名是否正常return signature.verify(decryptBASE64(sign));}/*** 生成密钥* * @param seed*      种子* @return 密钥对象* @throws Exception*/public static Map<String, Object> initKey(String seed) throws Exception {KeyPairGenerator keygen = KeyPairGenerator.getInstance(ALGORITHM);// 初始化随机产生器SecureRandom secureRandom = new SecureRandom();secureRandom.setSeed(seed.getBytes());keygen.initialize(KEY_SIZE, secureRandom);KeyPair keys = keygen.genKeyPair();DSAPublicKey publicKey = (DSAPublicKey) keys.getPublic();DSAPrivateKey privateKey = (DSAPrivateKey) keys.getPrivate();Map<String, Object> map = new HashMap<String, Object>(2);map.put(PUBLIC_KEY, publicKey);map.put(PRIVATE_KEY, privateKey);return map;}/*** 默认生成密钥* * @return 密钥对象* @throws Exception*/public static Map<String, Object> initKey() throws Exception {return initKey(DEFAULT_SEED);}/*** 取得私钥* * @param keyMap* @return* @throws Exception*/public static String getPrivateKey(Map<String, Object> keyMap)throws Exception {Key key = (Key) keyMap.get(PRIVATE_KEY);return encryptBASE64(key.getEncoded());}/*** 取得公钥* * @param keyMap* @return* @throws Exception*/public static String getPublicKey(Map<String, Object> keyMap)throws Exception {Key key = (Key) keyMap.get(PUBLIC_KEY);return encryptBASE64(key.getEncoded());}public static void test() throws Exception {String inputStr = "123";byte[] data = inputStr.getBytes();// 构建密钥Map<String, Object> keyMap = DSACoder.initKey();// 获得密钥String publicKey = DSACoder.getPublicKey(keyMap);String privateKey = DSACoder.getPrivateKey(keyMap);System.err.println("公钥:\r" + publicKey);System.err.println("私钥:\r" + privateKey);// 产生签名String sign = DSACoder.sign(data, privateKey);System.err.println("签名:\r" + sign);// 验证签名boolean status = DSACoder.verify(data, publicKey, sign);System.err.println("状态:\r" + status);}public static void main(String[] args) throws Exception {test();}
}

Java常见加密方式相关推荐

  1. Java常见加密使用和分析

    Java常见加密使用和分析 最近项目里碰到很多加解密的场景,使用多种加密的方式,大概整理了一下,一共有一下几种 加密方式 安全性 是否可逆 1 MD5 高 不可逆 2 AES 中 可逆 3 RSA 高 ...

  2. Python与常见加密方式

    Python与常见加密方式 前言 数据加密与解密通常是为了保证数据在传输过程中的安全性,自古以来就一直存在,古代主要应用在战争领域,战争中会有很多情报信息要传递,这些重要的信息都会经过加密,在发送到对 ...

  3. 密码学之常见加密方式(05)

    常见加密方式 文章目录 常见加密方式 前言 一.对称加密 二.DES加密 三.DES解密 Base64 算法简介 Base64 算法原理 Base64 构成原则 四.base64补等号测试 五.AES ...

  4. 最常见加密方式和Python实现

    前言 我们所说的加密方式,都是对二进制编码的格式进行加密的,对应到Python中,则是我们的Bytes. 所以当我们在Python中进行加密操作的时候,要确保我们操作的是Bytes,否则就会报错. 将 ...

  5. Java各种加密方式集锦(AES,DES,RSA,DSA,MD5,SHA)

    一. 什么是加密 加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容.在网络数据传输过程中会经常用到报文加密,通常是对报文体 ...

  6. 密码的常见加密方式,你都了解多少?

    文章目录 常见的8种加密方式 ①直接明文保存 ②使用对称加密算法来保存 ③使用MD5.SHA1等单向HASH算法保护密码 ④特殊的单向HASH算法 ⑤PBKDF2 ⑥BCrypt ⑦SCrypt ⑧A ...

  7. 如何使用Java对密码进行加密 Java Sah加密方式帮你实现加密

    我们在Web开发中,经常要保证密码的安全性,那么怎么对密码进行处理了?首先得进行加密吧!下面我介绍下Java 提供的SHA加密方式: SHA (Secure Hash Algorithm,译作安全散列 ...

  8. Python常见加密方式总结和实现

    一.前言 我们所说的加密方式,都是对二进制编码的格式进行加密的,对应到Python中,则是我们的Bytes. 所以当我们在Python中进行加密操作的时候,要确保我们操作的是Bytes,否则就会报错. ...

  9. python常见加密方式总结踩坑小贴士

    本文是向大家介绍python中常见的一些加密方式,在使用python的时候遇到数据加密的情况时,可以根据实际场景来选择加密的方式对数据进行加密,加强数据传输的安全性. 一.前言 日常工作中经常会看到各 ...

  10. 【计算机网络】常见加密方式

    写在前面 这周了解了https是如何实现安全传输的,其中涉及到了s加密的技术.所以,博主去又去学习了常见的加密方式,故写下这篇博客 一. 对称加密 1.介绍 这个比较好理解,也就是说加密和解密使用的是 ...

最新文章

  1. linux 6.4 安装dns,Linux 轻松上手 架设 CentOS 6.4 DNS+FTP ndash;(六)、安装设定vsftp
  2. java day10(续day9)
  3. 高仿真的类-AbstractApplicationContext
  4. 好文推荐 | 缓存与数据库一致性问题深度剖析 (修订)
  5. 【Hadoop Summit Tokyo 2016】Hivemall: Apache Hive/Spark/Pig 的可扩展机器学习库
  6. 2003正在锁定计算机,WIN2003 自动锁定怎么解决?
  7. Python接口自动化之unittest单元测试
  8. 收集几个AS3频谱代码SoundMixer.ComputeSpectrum()
  9. GitHub 标星 10,000+,Apache 顶级项目 ShardingSphere 的开源之路
  10. frontcon函数用不了_MQL4课程——账户信息函数和检测函数
  11. [VB.NET]各们,请问如何使用vb.net编写两个进程间消息通信的程序啊
  12. VBA模拟抽签关键代码
  13. 双舵轮AGV轨迹跟踪Pure Pursuit算法模型分析、python代码实现
  14. 【QGIS】无法定位程序输入点~于动态链接库~上
  15. 技术系统进化法则包括_八大技术系统进化法则主要包括哪些
  16. GD32 汽车诊断协议 J1850-VPW 测试
  17. oracle 12 去掉 cdb,Oracle 12c no-CDB转换为CDB
  18. 万物互联时代的兴起及其边缘算法效应
  19. 【特征选择】过滤式特征选择法
  20. Check failed: top_shape[j] == bottom[i]-shape(j) (1 vs. 2) All inputs must have the same shape, exc

热门文章

  1. Linux命令学习系列-用户切换su,sudo
  2. 在线Excel转XML工具
  3. python notebook右侧网页_Python Notebook介绍
  4. Android原生开发学习笔记(java)
  5. Flash助手推荐广告删除方法
  6. js制作随机抽奖,(指定数字范围内随机出现一个数字)
  7. python Django音乐推荐系统(课设、毕设、学习)
  8. Linux内核发包软件,pktgen--内核态发包工具
  9. C语言入门(15道经典题目)
  10. 安装SQL 2016的时候 Microsoft R Open 和 Microsoft R Server 安装文件的位置