加密算法全解析
加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容。加密方式大体上分为单向加密和双向加密,而双向加密又分为对称加密和非对称加密。
单向加密只是对信息进行了摘要计算,不能通过算法还原成明文,不能解密。双向加密就是对明文加密后形成密文,密文解密获得原文, 可以通过算法还原成明文。
一、单向加密
单向加密只是对信息进行了摘要计算,不能通过算法还原成明文,不能解密。
Java一般需要获取MessageDigest对象来实现单项加密(信息摘要)。常见的单向加密有:MD5, SHA, HMAC等
二、双向加密
双向加密就是对明文加密后形成密文,密文解密获得原文, 可以通过算法还原成明文。
(一)、对称加密
采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。
所谓对称,就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密。密钥是控制加密及解密过程的指令。
算法是一组规则,规定如何进行加密和解密。因此对称式加密本身不是安全的。
常用的对称加密有:DES、3DES、AES、 RC4、RC5、IDEA算法等
(二)、非对称加密
非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。 常用的非对称加密有:RSA, DH, DSA, ECC等
三、代码
package com.wytiger.lib.utils;
import android.util.Base64;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
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.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* 加密工具类
*
* @author wytiger
* @date 2016-5-6
*/
/**
*
* @author wytiger
* @date 2016年5月18日
*/
public class EncryptUtils {
/**
* BASE64编码解码
*/
public static class Base64Util {
/**
* 编码
*/
public static String encryptByBase64(String data) {
byte[] bytes = null;
try {
bytes = data.getBytes("utf-8");
} catch (Exception e) {
e.printStackTrace();
}
return Base64.encodeToString(bytes, Base64.DEFAULT);
}
/**
* 编码
*/
public static String encryptByBase64(byte[] bytes) {
return Base64.encodeToString(bytes, Base64.DEFAULT);
}
/**
* 译码
*/
public static String decryptByBase64ToStr(String encodeStr) {
String result = null;
try {
byte[] decodeBytes = Base64.decode(encodeStr, Base64.DEFAULT);
result = new String(decodeBytes, "utf-8");
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 译码
*/
public static byte[] decryptByBase64ToBytes(String encodeStr) {
return Base64.decode(encodeStr, Base64.DEFAULT);
}
}
/**
* 单向加密MD5,不能解密,一般用于验证参数是否正确
*/
public static class MD5Util {
// 加密算法MD5
private static final String ALGORITHM = "MD5";
/**
* MD5加密,单向加密,不能解密的
*/
public static byte[] encryptByMD5(String data) {
// String result = null;
byte[] resultBytes = null;
try {
// 获取一个信息加密的加密对象,传递一个加密算法名称的参数
MessageDigest md = MessageDigest.getInstance(ALGORITHM);
byte[] bytes = data.getBytes("utf-8");
// 编码
resultBytes = md.digest(bytes);
// result = new String(resultBytes);
} catch (Exception e) {
e.printStackTrace();
}
return resultBytes;
}
/**
* 一般情况下,先使用MD5加密,再使用BASE64编码传输
*/
public static String encryptByMD5AndBASE64(String data) {
byte[] bytes = encryptByMD5(data);
String buff = null;
try {
buff = new String(bytes, "utf-8");
} catch (Exception e) {
e.printStackTrace();
}
String result = Base64Util.encryptByBase64(buff);
return result;
}
}
/**
* 单向加密SHA
*
* @author wytiger
* @date 2016年5月18日
*/
public static class SHAUtil {
public static String SHA1(String decript) {
try {
MessageDigest digest = java.security.MessageDigest
.getInstance("SHA-1");
digest.update(decript.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
// 字节数组转换为 十六进制 数
for (int i = 0; i < messageDigest.length; i++) {
String shaHex = Integer
.toHexString(messageDigest[i] & 0xFF);
if (shaHex.length() < 2) {
hexString.append(0);
}
hexString.append(shaHex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
public static String SHA(String decript) {
try {
MessageDigest digest = java.security.MessageDigest
.getInstance("SHA");
digest.update(decript.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
// 字节数组转换为 十六进制 数
for (int i = 0; i < messageDigest.length; i++) {
String shaHex = Integer
.toHexString(messageDigest[i] & 0xFF);
if (shaHex.length() < 2) {
hexString.append(0);
}
hexString.append(shaHex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
}
/**
* 对称加密DES
*/
public static class DESUtil {
// 加密算法
private static final String ALGORITHM = "DES";
/**
* DES加密
*
* @param base64Key
* : 经BASE64二次加密的密钥
* @return
*/
public static byte[] encryptByDES(String base64Key, byte[] dataBytes)
throws Exception {
// BASE64解密
String encodeKey = Base64Util.decryptByBase64ToStr(base64Key);
// 获得key
Key key = getKey(encodeKey);
// 获得加密解密对象
Cipher cipher = Cipher.getInstance(ALGORITHM);
// 初始化,使用密钥进行加密
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(dataBytes);
}
/**
* DES解密
*
* @param base64Key
* : 经过BASE64编码且SecretKey加密的密钥
* @param encryptDataBytes
* :经过加密的数据
* @return :译码之后的字节数组
* @throws Exception
*/
public static byte[] decryptByDES(String base64Key,
byte[] encryptDataBytes) throws Exception {
// 获得key
Key k = getKey(Base64Util.decryptByBase64ToStr(base64Key));
// 获得加密解密对象
Cipher cipher = Cipher.getInstance(ALGORITHM);
// 解密
cipher.init(Cipher.DECRYPT_MODE, k);
return cipher.doFinal(encryptDataBytes);
}
/**
* 获取解码后密钥
*
* @param encodeKey
* : 经SecretKey加密的密钥字符串
* @return Key :解码后的密钥
*/
private static Key getKey(String encodeKey) {
SecretKey key = null;
try {
// 密钥参数
DESKeySpec dks = new DESKeySpec(encodeKey.getBytes());
SecretKeyFactory factory = SecretKeyFactory
.getInstance(ALGORITHM);
// 生成密钥
key = factory.generateSecret(dks);
} catch (Exception e) {
e.printStackTrace();
}
return key;
}
/**
* 生成密钥
*
* @param seed
* : 种子
* @return :经过SecretKey一次编码与BASE64二次编码的密钥字符串
*/
public static String initKey(String seed) {
// 获得密钥生成器所需要的随机参数
SecureRandom random = null;
if (null != seed) {
random = new SecureRandom(seed.getBytes());
} else {
random = new SecureRandom();
}
// 获取密钥生成器
KeyGenerator generator = null;
try {
generator = KeyGenerator.getInstance(ALGORITHM);
// 初始化,设置随机码
generator.init(random);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// 生成密钥,一个8位字节的
SecretKey key = generator.generateKey();
// 获得经过SecretKey编码后对应的字节数组
byte[] encodeKey = key.getEncoded();
// 对密钥字节数组进行BASE64编码传输
String base64Key = Base64Util.encryptByBase64(encodeKey);
return base64Key;
}
}
public static class DES3Util {
// KeyGenerator 提供对称密钥生成器的功能,支持各种算法
private KeyGenerator keygen;
// SecretKey 负责保存对称密钥
private SecretKey deskey;
// Cipher负责完成加密或解密工作
private Cipher c;
// 该字节数组负责保存加密的结果
private byte[] cipherByte;
public DES3Util() throws NoSuchAlgorithmException, NoSuchPaddingException {
// Security.addProvider(new com.sun.crypto.provider.SunJCE());
// 实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
keygen = KeyGenerator.getInstance("DESede");
// 生成密钥
deskey = keygen.generateKey();
// 生成Cipher对象,指定其支持的DES算法
c = Cipher.getInstance("DESede");
}
/**
* 对字符串加密
*
* @param str
* @return
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public byte[] encryptBy3DES(String str) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式
c.init(Cipher.ENCRYPT_MODE, deskey);
byte[] src = str.getBytes();
// 加密,结果保存进cipherByte
cipherByte = c.doFinal(src);
return cipherByte;
}
/**
* 对字符串解密
*
* @param buff
* @return
* @throws InvalidKeyException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public byte[] decryptBy3DES(byte[] buff) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式
c.init(Cipher.DECRYPT_MODE, deskey);
cipherByte = c.doFinal(buff);
return cipherByte;
}
}
/**
* 对称加密AES
*
* @author wytiger
* @date 2016年5月18日
*/
public static class AESUtil {
private static IvParameterSpec enc_iv;
private static SecretKeySpec enc_key;
private static Cipher cipherEnc;
// 密钥有限制,貌似不能随便改
private static String AESKEY = "0123456789abcdef";
private static String IvKey = "fedcba9876543210";
static final char[] HEX_CHAR_TABLE = { '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
static {// 初始化代码块
try {
cipherEnc = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
} catch (NoSuchPaddingException ex) {
ex.printStackTrace();
}
enc_key = new SecretKeySpec(AESKEY.getBytes(), "AES");
enc_iv = new IvParameterSpec(IvKey.getBytes());
}
/**
* 加密
*
* @param str
* 要加密的字符串
* @return 加密后的字符串
*/
public static String encrypt(String str) {
byte[] ret = null;
try {
enc_key = getKey(AESKEY);
cipherEnc.init(Cipher.ENCRYPT_MODE, enc_key, enc_iv);
String padRight = padRight(str,
((int) Math.ceil(str.length() / 16.0)) * 16);
byte[] origData = padRight.getBytes("UTF-8");
ret = cipherEnc.doFinal(origData);
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
return byteArray2HexString(ret);
}
/**
* 解密
*
* @param str
* 要解密的字符串
* @return
*/
public static String decrypt(String str) {
byte[] ret = null;
try {
cipherEnc.init(Cipher.DECRYPT_MODE, enc_key, enc_iv);
ret = cipherEnc.doFinal(hexString2ByteArray(str));
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
try {
return new String(ret, "UTF-8");
} catch (UnsupportedEncodingException e) {
return null;
}
}
public static String byteArray2HexString(byte[] b) {
if (b == null) {
return null;
}
final StringBuilder hex = new StringBuilder(2 * b.length);
for (final byte by : b) {
hex.append(HEX_CHAR_TABLE[(by & 0xF0) >> 4]).append(
HEX_CHAR_TABLE[(by & 0x0F)]);
}
return hex.toString();
}
public static byte[] hexString2ByteArray(String s) {
if (s == null) {
return null;
}
byte high, low;
int len = s.length() / 2;
byte[] b = new byte[len];
for (int i = 0, k = 0; i < len; i++, k += 2) {
high = (byte) (Character.digit(s.charAt(k), 16) & 0x0F);
low = (byte) (Character.digit(s.charAt(k + 1), 16) & 0x0F);
b[i] = (byte) ((high << 4) | low);
}
return b;
}
/**
* 将16进制转换为二进制
*/
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;
}
/**
* 将二进制转换成16进制
*/
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();
}
public static String padLeft(String s, int n) {
return String.format("%1$#" + n + "s", s);
}
public static String padRight(String s, int n) {
return String.format("%1$-" + n + "s", s);
}
/**
* 获取适配密钥
*/
private static SecretKeySpec getKey(String strKey) throws Exception {
byte[] arrBTmp = strKey.getBytes();
byte[] arrB = new byte[16]; // 创建一个空的16位字节数组(默认值为0)
for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
arrB[i] = arrBTmp[i];
}
SecretKeySpec skeySpec = new SecretKeySpec(arrB, "AES");
return skeySpec;
}
/**
* 加密
*
* @param content
* 需要加密的内容
* @return 解密后的字节数组
*/
public static byte[] encryptString2Bytes(String content) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(AESKEY.getBytes()));
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);
return result; // 加密
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
/**
* 对称加密RC4
*
* @author wytiger
* @date 2016年5月18日
*/
public static class RC4Util {
public static String decry_RC4(byte[] data, String key) {
if (data == null || key == null) {
return null;
}
return asString(RC4Base(data, key));
}
public static String decry_RC4(String data, String key) {
if (data == null || key == null) {
return null;
}
return new String(RC4Base(HexString2Bytes(data), key));
}
public static byte[] encry_RC4_byte(String data, String key) {
if (data == null || key == null) {
return null;
}
byte b_data[] = data.getBytes();
return RC4Base(b_data, key);
}
public static String encry_RC4_string(String data, String key) {
if (data == null || key == null) {
return null;
}
return toHexString(asString(encry_RC4_byte(data, key)));
}
private static String asString(byte[] buf) {
StringBuffer strbuf = new StringBuffer(buf.length);
for (int i = 0; i < buf.length; i++) {
strbuf.append((char) buf[i]);
}
return strbuf.toString();
}
private static byte[] initKey(String aKey) {
byte[] b_key = aKey.getBytes();
byte state[] = new byte[256];
for (int i = 0; i < 256; i++) {
state[i] = (byte) i;
}
int index1 = 0;
int index2 = 0;
if (b_key == null || b_key.length == 0) {
return null;
}
for (int i = 0; i < 256; i++) {
index2 = ((b_key[index1] & 0xff) + (state[i] & 0xff) + index2) & 0xff;
byte tmp = state[i];
state[i] = state[index2];
state[index2] = tmp;
index1 = (index1 + 1) % b_key.length;
}
return state;
}
private static String toHexString(String s) {
String str = "";
for (int i = 0; i < s.length(); i++) {
int ch = (int) s.charAt(i);
String s4 = Integer.toHexString(ch & 0xFF);
if (s4.length() == 1) {
s4 = '0' + s4;
}
str = str + s4;
}
return str;// 0x表示十六进制
}
private static byte[] HexString2Bytes(String src) {
int size = src.length();
byte[] ret = new byte[size / 2];
byte[] tmp = src.getBytes();
for (int i = 0; i < size / 2; i++) {
ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
}
return ret;
}
private static byte uniteBytes(byte src0, byte src1) {
char _b0 = (char)Byte.decode("0x" + new String(new byte[] { src0 }))
.byteValue();
_b0 = (char) (_b0 << 4);
char _b1 = (char)Byte.decode("0x" + new String(new byte[] { src1 }))
.byteValue();
byte ret = (byte) (_b0 ^ _b1);
return ret;
}
public static byte[] RC4Base (byte [] input, String mKkey) {
int x = 0;
int y = 0;
byte key[] = initKey(mKkey);
int xorIndex;
byte[] result = new byte[input.length];
for (int i = 0; i < input.length; i++) {
x = (x + 1) & 0xff;
y = ((key[x] & 0xff) + y) & 0xff;
byte tmp = key[x];
key[x] = key[y];
key[y] = tmp;
xorIndex = ((key[x] & 0xff) + (key[y] & 0xff)) & 0xff;
result[i] = (byte) (input[i] ^ key[xorIndex]);
}
return result;
}
}
/**
* 非对称加密RSA
*
* @author Administrator
*/
public static class RSAUtil {
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";
private static final int KEY_LENGTH = 1024;
/**
* 使用私钥对数据进行加密
*
* @param data
* @param base64Key
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String base64Key)
throws Exception {
// 解码密钥
byte[] keyBytes = Base64Util.decryptByBase64ToBytes(base64Key);
// 获得私钥
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateKey = factory.generatePrivate(spec);
// 使用私钥对数据加密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] bytes = cipher.doFinal(data);
return bytes;
}
/**
* 使用公钥对数据进行加密
*
* @param data
* @param base64Key
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String base64Key)
throws Exception {
// 解码密钥
byte[] keyBytes = Base64Util.decryptByBase64ToBytes(base64Key);
// 获得公钥
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicKey = factory.generatePublic(spec);
// 使用公钥对数据加密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] bytes = cipher.doFinal(data);
return bytes;
}
/**
* 使用公钥解密数据
*
* @param data
* @param base64Key
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] data, String base64Key)
throws Exception {
// 解码密钥
byte[] keyBytes = Base64Util.decryptByBase64ToBytes(base64Key);
// 获得公钥
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicKey = factory.generatePublic(spec);
// 使用公钥对数据
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] bytes = cipher.doFinal(data);
return bytes;
}
/**
* 使用私钥解密数据
*
* @param data
* @param base64Key
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] data, String base64Key)
throws Exception {
// 解码密钥
byte[] keyBytes = Base64Util.decryptByBase64ToBytes(base64Key);
// 获得私钥
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateKey = factory.generatePrivate(spec);
// 使用私钥对数据加密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] bytes = cipher.doFinal(data);
return bytes;
}
/**
* 初始化密钥对,将生成的密钥对存放到Map集合
*
* @return
* @throws Exception
*/
public static Map<String, Object> initKey() throws Exception {
KeyPairGenerator generator = KeyPairGenerator
.getInstance(KEY_ALGORITHM);
// 指定密钥长度
generator.initialize(KEY_LENGTH);
// 生产密钥对
KeyPair keyPair = generator.generateKeyPair();
// 分别获得公钥与私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 将密钥存放到map集合并返回该map对象
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PRIVATE_KEY, privateKey);
keyMap.put(PUBLIC_KEY, publicKey);
return keyMap;
}
/**
* 获得BASE64编码的私钥
*
* @param keyMap
* :存放元素私钥的集合
* @return BASE64编码的私钥字符串
*/
public static String getBase64PrivateKey(Map<String, Object> keyMap) {
// 获取私钥
Key privateKey = (Key) keyMap.get(PRIVATE_KEY);
// 对私钥进行BASE64编码
String base64PrivateKey = Base64Util.encryptByBase64(privateKey
.getEncoded());
// 返回编码后的私钥
return base64PrivateKey;
}
/**
* 获得BASE64编码的公钥
*
* @param keyMap
* :存放元素私钥的集合
* @return BASE64编码的公钥字符串
*/
public static String getBase64PublicKey(Map<String, Object> keyMap) {
// 获取私钥
Key publicKey = (Key) keyMap.get(PUBLIC_KEY);
// 对私钥进行BASE64编码
String base64PrivateKey = Base64Util.encryptByBase64(publicKey
.getEncoded());
// 返回编码后的私钥
return base64PrivateKey;
}
/**
* 用私钥对信息生成数字签名
*
* @param data
* 加密数据
* @param privateKey
* 私钥
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey)
throws Exception {
// 解密由base64编码的私钥
byte[] keyBytes = Base64Util.decryptByBase64ToBytes(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 Base64Util.encryptByBase64(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 = Base64Util.decryptByBase64ToBytes(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(Base64Util.decryptByBase64ToBytes(sign));
}
}
}