数据加密小结(初级)

越来越发现学过的东西不记下来,一段时间就忘得一干二净。

以下为前段时间了解的数据加密的初级知识。

 

加密的本质:通过算法,将有序可识别的字符串,转换成肉眼不可识别的字符串。

分类:

  • 一.单向加密算法
  • 二.对称加密算法
  • 三.非对称加密算法

一.单项加密算法

  加密过程不可逆 .

  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

 

  • 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 慢。

public class Md5Test {
    public  static String MD5(String s) {

        if(s==null && s.equals("")){
            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");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
//                定义转换成16进制的算法
                str[k++] = hexDigits[byte0 >>> 5 & 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("加密"));
    }
}
public class Base64Test {

//    解密
    public static String  getFromBase64(String s){
        byte[] b = null;
        String result = null;
        if (s != null) {
            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 (b != null) {
            result = new BASE64Encoder().encode(b);
        }
        return result;
    }

    public static void main(String [] args){
        System.out.println(getBase64("admin"));
        System.out.println(getFromBase64("YWRtaW4="));
    }
}
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));
    }
}

base64

MD5

SHA

对称加密算法

模型:

 
 
 
 
 

 加密过程可逆

 
 
 

工具:秘钥(一个)

加密

解密

 
 

DES,全称为“Data Encryption Standard”,中文名为“数据加密标准”;

3DES,也就是“Triple DES”,中文名“三重数据加密算法”;

AES,全称为“Advanced Encryption Standard”,中文名“高级加密标准

非对称加密算法

模型:

 
 
 
 
 

加密过程可逆 

 
 
 

工具:秘钥(两个)

加密

解密

 
 
 
posted @ 2016-11-21 15:16  it馅儿包子  阅读(245)  评论(0编辑  收藏  举报