数据加密小结(初级)
越来越发现学过的东西不记下来,一段时间就忘得一干二净。
以下为前段时间了解的数据加密的初级知识。
加密的本质:通过算法,将有序可识别的字符串,转换成肉眼不可识别的字符串。
分类:
- 一.单向加密算法
- 二.对称加密算法
- 三.非对称加密算法
一.单项加密算法
加密过程不可逆 .
BASE64 严格地说,属于编码格式,而非加密算法;
MD5(Message Digest algorithm 5,信息摘要算法);
SHA(Secure Hash Algorithm,安全散列算法);
HMAC(hash message authentication code,散列消息鉴别码);
SHA-1 与 MD5 的比较
因为二者均由 MD4 导出,SHA-1 和 MD5 彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:
对强行攻击的安全性
最显著和最重要的区别是 SHA-1 摘要比 MD5 摘要长 32 位。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对 MD5 是 2^128 数量级的操作,而对 SHA-1 则是 2^160 数量级的操作。这样,SHA-1 对强行攻击有更大的强度。
对密码分析的安全性
由于 MD5 的设计,易受密码分析的攻击,SHA-1 显得不易受这样的攻击。
速度
在相同的硬件上,SHA-1 的运行速度比 MD5 慢。
base64DEMO:
public class Base64Test {
// 解密
public static String getFromBase64(String s){
byte[] b = null;
String result = null;
if (!Strings.isNullOrEmpty(s)) {
BASE64Decoder decoder=new BASE64Decoder();
try {
b=decoder.decodeBuffer(s);
result=new String(b,"utf-8");
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
// 加密
public static String getBase64(String s){
byte[] b = null;
String result = null;
try {
b=s.getBytes("utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if (!Strings.isNullOrEmpty(s)) {
result = new BASE64Encoder().encode(b);
}
return result;
}
public static void main(String [] args){
System.out.println(getBase64("admin"));
System.out.println(getFromBase64("YWRtaW4="));
}
}
MD5 demo:
public class Md5Test {
public static String MD5(String s) {
if(Strings.isNullOrEmpty(s)){
return null;
}
char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
try {
byte[] btInput = s.getBytes();
// 获得MD5摘要算法的 MessageDigest 对象
// MessageDigest mdInst = MessageDigest.getInstance("MD5");
MessageDigest mdInst = MessageDigest.getInstance("SHA");
// MessageDigest mdInst = MessageDigest.getInstance("SHA-1");
// 使用指定的字节更新摘要
mdInst.update(btInput);
// 获得密文
byte[] md = mdInst.digest();
// 把密文转换成十六进制的字符串形式
int j = md.length;
char str[] = new char[j * 2];
// 调用api将byte转成十六进制字符
System.out.println( new String(new Hex().encode(md)));
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
// 定义转换成16进制的算法
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
System.out.println(MD5("admin"));
System.out.println(MD5("加密"));
}
}
SHA demo:
public class ShaTest {
/**
* 定义加密方式
*/
private final static String KEY_SHA = "SHA";
private final static String KEY_SHA1 = "SHA-1";
private final static String KEY_SHA224 = "SHA-224";
private final static String KEY_SHA256 = "SHA-256";
/**
* 全局数组
*/
private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
/**
* 构造函数
*/
public ShaTest() {}
/**
* SHA 加密
* @param data 需要加密的字符串
* @return 加密之后的字符串
* @throws Exception
*/
public static String encryptSHA(String data) throws Exception {
// 验证传入的字符串
if (Strings.isNullOrEmpty(data)) {
return "";
}
// 创建具有指定算法名称的信息摘要
MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
// 使用指定的字节数组对摘要进行最后更新
sha.update(data.getBytes());
// 完成摘要计算
byte[] bytes = sha.digest();
// 将得到的字节数组变成字符串返回
return byteArrayToHexString(bytes);
}
/**
* 将一个字节转化成十六进制形式的字符串
* @param b 字节数组
* @return 字符串
*/
private static String byteToHexString(byte b) {
int ret = b;
//System.out.println("ret = " + ret);
if (ret < 0) {
ret += 256;
}
int m = ret / 16;
int n = ret % 16;
return hexDigits[m] + hexDigits[n];
}
/**
* 转换字节数组为十六进制字符串
* @param bytes 字节数组
* @return 十六进制字符串
*/
private static String byteArrayToHexString(byte[] bytes) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
sb.append(byteToHexString(bytes[i]));
}
return sb.toString();
}
public static void main(String[] args) throws Exception {
String key = "123";
System.out.println(encryptSHA(key));
}
}
HMAC demo:
public class HmacTest {
/**
* 定义加密方式
* MAC算法可选以下多种算法
* <pre>
* HmacMD5
* HmacSHA1
* HmacSHA256
* HmacSHA384
* HmacSHA512
* </pre>
*/
private final static String KEY_MAC = "HmacSHA1";
/**
* 全局数组
*/
private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
/**
* 构造函数
*/
public HmacTest() {}
/**
* BASE64 加密
* @param key 需要加密的字节数组
* @return 字符串
* @throws Exception
*/
public static String encryptBase64(byte[] key) throws Exception {
return (new BASE64Encoder()).encodeBuffer(key);
}
/**
* BASE64 解密
* @param key 需要解密的字符串
* @return 字节数组
* @throws Exception
*/
public static byte[] decryptBase64(String key) throws Exception {
return (new BASE64Decoder()).decodeBuffer(key);
}
/**
* 初始化HMAC密钥
* @return
*/
public static String init() {
SecretKey key;
String str = "";
try {
KeyGenerator generator = KeyGenerator.getInstance(KEY_MAC);
key = generator.generateKey();
str = encryptBase64(key.getEncoded());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
/**
* HMAC加密
* @param data 需要加密的字节数组
* @param key 密钥
* @return 字节数组
*/
public static byte[] encryptHMAC(byte[] data, String key) {
SecretKey secretKey;
byte[] bytes = null;
try {
secretKey = new SecretKeySpec(decryptBase64(key), KEY_MAC);
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
bytes = mac.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return bytes;
}
/**
* HMAC加密
* @param data 需要加密的字符串
* @param key 密钥
* @return 字符串
*/
public static String encryptHMAC(String data, String key) {
if (Strings.isNullOrEmpty(data)) {
return null;
}
byte[] bytes = encryptHMAC(data.getBytes(), key);
return byteArrayToHexString(bytes);
}
/**
* 将一个字节转化成十六进制形式的字符串
* @param b 字节数组
* @return 字符串
*/
private static String byteToHexString(byte b) {
int ret = b;
//System.out.println("ret = " + ret);
if (ret < 0) {
ret += 256;
}
int m = ret / 16;
int n = ret % 16;
return hexDigits[m] + hexDigits[n];
}
/**
* 转换字节数组为十六进制字符串
* @param bytes 字节数组
* @return 十六进制字符串
*/
private static String byteArrayToHexString(byte[] bytes) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
sb.append(byteToHexString(bytes[i]));
}
return sb.toString();
}
public static void main(String[] args) throws Exception {
String key = HmacTest.init();
System.out.println("Mac密钥:" + key);
String word = "123";
System.out.println(encryptHMAC(word, key));
System.out.println(encryptHMAC("0f93ddc47951f20cd972110a7d395be7754df583",key));
}
}
base64在sha,hmac中基本都有用到,先用base64先转码以下,再用相应的加密方法。
md5单项加密,适用于对用户的密码进行加密;
sha这个加密方法我曾经在redis官方文档里有看到,不知道用没用过,在听公司前辈讲,win系统中使用的加密方法就有sha。
二.对称加密算法(加密过程可逆)
方法:
DES,全称为“Data Encryption Standard”,中文名为“数据加密标准”;
3DES,也就是“Triple DES”,中文名“三重数据加密算法”;
AES,全称为“Advanced Encryption Standard”,中文名“高级加密标准。
由于三类方法用的api都是密码器cipher,只是参数不同,
所以我直接写了一个demo,参数请看注释:
public class DesTest {
/**
* 定义加密方式
*/
// private final static String KEY = "AES";
private final static String KEY = "DES";
// private final static String KEY = "DESede";
// DES算法必须是56位
// DESede算法可以是112位或168位
// AES算法可以是128、192、256位
private final static Integer KEY_num = 56;
/**
* 全局数组
*/
private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
/**
* 初始化密钥
* @return
*/
public static SecretKey init() {
SecretKey key =null;
try {
KeyGenerator generator = KeyGenerator.getInstance(KEY);// 获取密匙生成器
// DES算法必须是56位
// DESede算法可以是112位或168位
// AES算法可以是128、192、256位
generator.init(KEY_num);// 初始化
key = generator.generateKey();// 生成密匙,可用多种方法来保存密匙
} catch (Exception e) {
e.printStackTrace();
}
return key;
}
/**
* DES 解密
* @param data 需要解密的字符串
* @param key 密钥
* @return
*/
public static String decryptDES(String data, SecretKey key) {
// 验证传入的字符串
if (Strings.isNullOrEmpty(data)) {
return "";
}
// 调用解密方法完成解密
byte[] bytes = null;
try {
Cipher cipher = Cipher.getInstance(KEY);// 创建密码器
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
bytes = cipher.doFinal(hexString2Bytes(data));// 解密
} catch (Exception e) {
e.printStackTrace();
}
// 将得到的字节数组变成字符串返回
return new String(bytes);
}
/**
* DES 加密
* @param data 需要加密的字符串
* @param key 密钥
* @return
*/
public static String encryptDES(String data, SecretKey key) {
// 验证传入的字符串
if (Strings.isNullOrEmpty(data)) {
return "";
}
// 调用加密方法完成加密
byte[] bytes=null;
try {
Cipher cipher = Cipher.getInstance(KEY);// 创建密码器
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
bytes = cipher.doFinal(data.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
// 将得到的字节数组变成字符串(十六进制)返回
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
sb.append(byteToHexString(bytes[i]));
}
return sb.toString();
}
/**
* 将一个字节转化成十六进制形式的字符串
* @param b 字节数组
* @return 字符串
*/
private static String byteToHexString(byte b) {
int ret = b;
//System.out.println("ret = " + ret);
if (ret < 0) {
ret += 256;
}
int m = ret / 16;
int n = ret % 16;
return hexDigits[m] + hexDigits[n];
}
/**
* 转换十六进制字符串为字节数组
* @param hexstr 十六进制字符串
* @return
*/
public static byte[] hexString2Bytes(String hexstr) {
byte[] b = new byte[hexstr.length() / 2];
int j = 0;
for (int i = 0; i < b.length; i++) {
char c0 = hexstr.charAt(j++);
char c1 = hexstr.charAt(j++);
b[i] = (byte) ((parse(c0) << 4) | parse(c1));
}
return b;
}
/**
* 转换字符类型数据为整型数据
* @param c 字符
* @return
*/
private static int parse(char c) {
if (c >= 'a')
return (c - 'a' + 10) & 0x0f;
if (c >= 'A')
return (c - 'A' + 10) & 0x0f;
return (c - '0') & 0x0f;
}
/**
* 测试方法
* @param args
*/
public static void main(String[] args) {
SecretKey key = DesTest.init();
System.out.println("DES密钥: " + key.getAlgorithm());
String word = "123";
String encWord = encryptDES(word, key);
System.out.println(word + "加密后:" + encWord);
System.out.println(word + "解密后:" + decryptDES(encWord, key));
}
}
三:非对称加密算法
RSA;
DH,全称为“Diffie-Hellman”,他是一种确保共享KEY安全穿越不安全网络的方法,也就是常说的密钥一致协议。
rsa demo:
public class RsaTest {
/**
* 定义加密方式
*/
private final static String KEY_RSA = "RSA";
/**
* 定义签名算法
*/
private final static String KEY_RSA_SIGNATURE = "MD5withRSA";
/**
* 定义公钥算法
*/
private final static String KEY_RSA_PUBLICKEY = "RSAPublicKey";
/**
* 定义私钥算法
*/
private final static String KEY_RSA_PRIVATEKEY = "RSAPrivateKey";
/**
* 初始化密钥
* @return
*/
public static Map<String, Object> init() {
Map<String, Object> map = null;
try {
KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_RSA);
generator.initialize(1024);//秘钥长度
KeyPair keyPair = generator.generateKeyPair();//生成密钥对
// 公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 将密钥封装为map
map = Maps.newHashMap();
map.put(KEY_RSA_PUBLICKEY, publicKey);
map.put(KEY_RSA_PRIVATEKEY, privateKey);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return map;
}
/**
* 用私钥对信息生成数字签名
* @param data 加密数据
* @param privateKey 私钥
* @return
*/
public static String sign(byte[] data, String privateKey) {
String str = "";
try {
// 解密由base64编码的私钥
byte[] bytes = decryptBase64(privateKey);
// 构造PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(bytes);
// 指定的加密算法
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
// 取私钥对象
PrivateKey key = factory.generatePrivate(pkcs);
// 用私钥对信息生成数字签名
Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
signature.initSign(key);
signature.update(data);
str = encryptBase64(signature.sign());
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
/**
* 校验数字签名
* @param data 加密数据
* @param publicKey 公钥
* @param sign 数字签名
* @return 校验成功返回true,失败返回false
*/
public static boolean verify(byte[] data, String publicKey, String sign) {
boolean flag = false;
try {
// 解密由base64编码的公钥
byte[] bytes = decryptBase64(publicKey);
// 构造X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
// 指定的加密算法
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
// 取公钥对象
PublicKey key = factory.generatePublic(keySpec);
// 用公钥验证数字签名
Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
signature.initVerify(key);
signature.update(data);
flag = signature.verify(decryptBase64(sign));
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
/**
* 私钥解密
* @param data 加密数据
* @param key 私钥
* @return
*/
public static byte[] decryptByPrivateKey(byte[] data, String key) {
byte[] result = null;
try {
// 对私钥解密
byte[] bytes = decryptBase64(key);
// 取得私钥
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
PrivateKey privateKey = factory.generatePrivate(keySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
result = cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 私钥解密
* @param data 加密数据
* @param key 公钥
* @return
*/
public static byte[] decryptByPublicKey(byte[] data, String key) {
byte[] result = null;
try {
// 对公钥解密
byte[] bytes = decryptBase64(key);
// 取得公钥
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
PublicKey publicKey = factory.generatePublic(keySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
result = cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 公钥加密
* @param data 待加密数据
* @param key 公钥
* @return
*/
public static byte[] encryptByPublicKey(byte[] data, String key) {
byte[] result = null;
try {
byte[] bytes = decryptBase64(key);
// 取得公钥
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
// generatePublic:根据提供的密钥规范(密钥材料)生成私钥对象。
PublicKey publicKey = factory.generatePublic(keySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
result = cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 私钥加密
* @param data 待加密数据
* @param key 私钥
* @return
*/
public static byte[] encryptByPrivateKey(byte[] data, String key) {
byte[] result = null;
try {
byte[] bytes = decryptBase64(key);
// 取得私钥
// 此类表示按照 ASN.1 类型 PrivateKeyInfo 进行编码的专用密钥的 ASN.1 编码。
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
// generatePrivate:根据提供的密钥规范(密钥材料)生成私钥对象。
PrivateKey privateKey = factory.generatePrivate(keySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
result = cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 获取公钥
* @param map
* @return
*/
public static String getPublicKey(Map<String, Object> map) {
String str = "";
try {
Key key = (Key) map.get(KEY_RSA_PUBLICKEY);
str = encryptBase64(key.getEncoded());
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
/**
* 获取私钥
* @param map
* @return
*/
public static String getPrivateKey(Map<String, Object> map) {
String str = "";
try {
Key key = (Key) map.get(KEY_RSA_PRIVATEKEY);
str = encryptBase64(key.getEncoded());
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
/**
* 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);
}
/**
* 测试方法
* @param args
*/
public static void main(String[] args) {
String privateKey = "";
String publicKey = "";
// 生成公钥私钥
Map<String, Object> map = init();
publicKey = getPublicKey(map);
privateKey = getPrivateKey(map);
System.out.println("公钥: \n\r" + publicKey);
System.out.println("私钥: \n\r" + privateKey);
System.out.println("公钥加密--------私钥解密");
String word = "你好,世界!";
byte[] encWord = encryptByPublicKey(word.getBytes(), publicKey);
String decWord = new String(decryptByPrivateKey(encWord, privateKey));
System.out.println("加密前: " + word + "\n\r" + "解密后: " + decWord);
System.out.println("私钥加密--------公钥解密");
String english = "Hello, World!";
byte[] encEnglish = encryptByPrivateKey(english.getBytes(), privateKey);
String decEnglish = new String(decryptByPublicKey(encEnglish, publicKey));
System.out.println("加密前: " + english + "\n\r" + "解密后: " + decEnglish);
System.out.println("私钥签名——公钥验证签名");
// 产生签名
String sign = sign(encEnglish, privateKey);
System.out.println("签名:\r" + sign);
// 验证签名
boolean status = verify(encEnglish, publicKey, sign);
System.out.println("状态:\r" + status);
}
}
//生成密匙 KeyPairGenerator
//创建密码器 Cipher
//Only RSAPublicKeySpec and X509EncodedKeySpec supported for RSA public keys
//Only RSAPrivate(Crt)KeySpec and PKCS8EncodedKeySpec supported for RSA private keys
dh demo:
public class DhTest {
/**
* 定义加密方式
*/
private static final String KEY_DH = "DH";
/**
* 默认密钥字节数
*/
private static final int KEY_SIZE = 1024;
/**
* DH加密下需要一种对称加密算法对数据加密,这里我们使用DES,也可以使用其他对称加密算法
*/
private static final String KEY_DH_DES = "DES";
private static final String KEY_DH_PUBLICKEY = "DHPublicKey";
private static final String KEY_DH_PRIVATEKEY = "DHPrivateKey";
/**
* 初始化甲方密钥
* @return
*/
public static Map<String, Object> init() {
Map<String, Object> map = null;
try {
KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_DH);
generator.initialize(KEY_SIZE);
KeyPair keyPair = generator.generateKeyPair();
// 甲方公钥
DHPublicKey publicKey = (DHPublicKey) keyPair.getPublic();
// 甲方私钥
DHPrivateKey privateKey = (DHPrivateKey) keyPair.getPrivate();
map = Maps.newHashMap();
map.put(KEY_DH_PUBLICKEY, publicKey);
map.put(KEY_DH_PRIVATEKEY, privateKey);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return map;
}
/**
* 初始化乙方密钥
* @param key 甲方密钥
* @return
*/
public static Map<String, Object> init(String key) {
Map<String, Object> map = null;
try {
// 解析甲方密钥
byte[] bytes = decryptBase64(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
KeyFactory factory = KeyFactory.getInstance(KEY_DH);
PublicKey publicKey = factory.generatePublic(keySpec);
// 由甲方公钥构建乙方密钥
DHParameterSpec spec = ((DHPublicKey) publicKey).getParams();
KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_DH);
generator.initialize(spec);
KeyPair keyPair = generator.generateKeyPair();
// 乙方公钥
DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
// 乙方私钥
DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();
map = Maps.newHashMap();
map.put(KEY_DH_PUBLICKEY, dhPublicKey);
map.put(KEY_DH_PRIVATEKEY, dhPrivateKey);
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
/**
* DH 加密
* @param data 带加密数据
* @param publicKey 甲方公钥
* @param privateKey 乙方私钥
* @return
*/
public static byte[] encryptDH(byte[] data, String publicKey, String privateKey) {
byte[] bytes = null;
try {
// 生成本地密钥
SecretKey secretKey = getSecretKey(publicKey, privateKey);
System.out.println("secretKey`````````````````"+secretKey);
// 数据加密
Cipher cipher = Cipher.getInstance(secretKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
bytes = cipher.doFinal(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return bytes;
}
/**
* DH 解密
* @param data 待解密数据
* @param publicKey 乙方公钥
* @param privateKey 甲方私钥
* @return
*/
public static byte[] decryptDH(byte[] data, String publicKey, String privateKey) {
byte[] bytes = null;
try {
// 生成本地密钥
SecretKey secretKey = getSecretKey(publicKey, privateKey);
System.out.println("secretKey`````````````````"+secretKey);
// 数据解密
Cipher cipher = Cipher.getInstance(secretKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, secretKey);
bytes = cipher.doFinal(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return bytes;
}
/**
* 取得私钥
* @param map
* @return
*/
public static String getPrivateKey(Map<String, Object> map) {
String str = "";
try {
Key key = (Key) map.get(KEY_DH_PRIVATEKEY);
str = encryptBase64(key.getEncoded());
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
/**
* 取得公钥
* @param map
* @return
*/
public static String getPublicKey(Map<String, Object> map) {
String str = "";
try {
Key key = (Key) map.get(KEY_DH_PUBLICKEY);
str = encryptBase64(key.getEncoded());
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
/**
* 构建本地密钥
* @param publicKey 公钥
* @param privateKey 私钥
* @return
*/
private static SecretKey getSecretKey(String publicKey, String privateKey) {
SecretKey secretKey = null;
try {
// 初始化公钥
byte[] publicBytes = decryptBase64(publicKey);
KeyFactory factory = KeyFactory.getInstance(KEY_DH);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
PublicKey localPublicKey = factory.generatePublic(keySpec);
// 初始化私钥
byte[] privateBytes = decryptBase64(privateKey);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privateBytes);
PrivateKey localPrivateKey = factory.generatePrivate(spec);
KeyAgreement agreement = KeyAgreement.getInstance(factory.getAlgorithm());
agreement.init(localPrivateKey);
agreement.doPhase(localPublicKey, true);
// 生成本地密钥
secretKey = agreement.generateSecret(KEY_DH_DES);
} catch (Exception e) {
e.printStackTrace();
}
return secretKey;
}
/**
* 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);
}
/**
* 测试方法
* @param args
*/
public static void main(String[] args) {
// 生成甲方密钥对
Map<String, Object> mapA = init();
String publicKeyA = getPublicKey(mapA);
String privateKeyA = getPrivateKey(mapA);
System.out.println("甲方公钥:\n" + publicKeyA);
System.out.println("甲方私钥:\n" + privateKeyA);
// 由甲方公钥产生本地密钥对
Map<String, Object> mapB = init(publicKeyA);
String publicKeyB = getPublicKey(mapB);
String privateKeyB = getPrivateKey(mapB);
System.out.println("乙方公钥:\n" + publicKeyB);
System.out.println("乙方私钥:\n" + privateKeyB);
String word = "abc";
System.out.println("原文: " + word);
// 由甲方公钥,乙方私钥构建密文
byte[] encWord = encryptDH(word.getBytes(), publicKeyA, privateKeyB);
// 由乙方公钥,甲方私钥解密
byte[] decWord = decryptDH(encWord, publicKeyB, privateKeyA);
System.out.println("解密: " + new String(decWord));
}
}
单向加密: 不要求识别原始字符串,只要保证字符串与原始字符串相同。 用户注册账号,保存密码,先加密,在保存到数据库,登陆时,将用户输入的密码单向加密获取加密后的字符串A,去数据库查找字符串A。
对称加密: 甲乙双方使用相同的秘钥(一个)。
要求在 甲方发送到乙方 的传输过程中的是 原文加密后的字符串;且在乙方可以解密成原文。
非对称加密: 甲乙上双方各产生一对秘钥,公钥公开,用于加密原文,私钥用于解密接收到的字符串,还原成原文。rsa
甲方产生一对秘钥,公开公钥,乙方根据甲方提供的公钥产生自己的一对秘钥。dh:
构件密文:甲方的公钥+乙方的私钥-----》加密秘钥;(乙方发送给甲方)
解密: 甲方的秘钥+乙方的公钥-------》解密秘钥;(甲方接受原文)。
(demo手敲,敲代码是方式,目的是更懂代码。)
以上。
参考博客:http://blog.csdn.net/happylee6688/article/category/2902645