加密算法SHA、RSA、DES、凯撒加密、Blowfish的java实现
最早使用的加密就是MD5加密了。但是陆续发现一些非常好的加密算法。总结一下:
1,SHA():
SHA 家族 SHA (Secure Hash Algorithm,译作安全散列算法或或者安全哈希算法)
是美国国家安全局 (NSA) 设计,美国国家标准与技术研究院 (NIST) 发布的一系列密码散列函数。
非常高大上吧,但是用法非常简单。只需要一个commons-codec-1.8.jar
demo:
import org.apache.commons.codec.digest.DigestUtils;
* @author xujie
* @date 2016-4-14
* @version 1.0.1
*
public class Test1 {
public static void main(String[] args) {
//SHA 家族 SHA (Secure Hash Algorithm,译作安全散列算法)
//是美国国家安全局 (NSA) 设计,美国国家标准与技术研究院 (NIST) 发布的一系列密码散列函数。
String result =DigestUtils.sha256Hex("123456");
System.out.println("result="+result);
// SHA-384
String result2 = DigestUtils.sha384Hex("123456");
System.out.println("result2="+result2);
// SHA-512
String result3 = DigestUtils.sha512Hex("123456");
System.out.println("result3="+result3);
// SHA-1
String result4 = DigestUtils.sha1Hex("123456");
System.out.println("result4="+result4);
}
}
结果:
result=8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
result2=0a989ebc4a77b56a6e2bb7b19d995d185ce44090c13e2984b7ecc6d446d4b61ea9991b76a4c2f04b1b4d244841449454
result3=ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413
result4=7c4a8d09ca3762af61e59520943dc26494f8941b
2,非对称加密算法--RSA
//非对称加密的特点是有两把钥匙,公钥和私钥。公钥加密只能私钥解密;私钥加密只能公钥解密。
*
* 在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。
* 加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。
* RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。
* 1987年首次公布,当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
* 这种加密算法的特点主要是密钥的变化。DES只有一个密钥,相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。
* RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验,确保数据在传输过程中不被修改。
*
demo:
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 javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
* @author xujie
* @date 2016-4-14
* @version 1.0.1
*
public class Test2 {
static final String A = "RSA";
static final String B = "MD5withRSA";
static String publicKey = null;
static String privateKey = null;
public static void main(String[] args) throws Exception {
//Java非对称加密算法--RSA
//非对称加密的特点是有两把钥匙,公钥和私钥。公钥加密只能私钥解密;私钥加密只能公钥解密。
// 生成公钥和私钥
generatorKeyPair();
String source = "我是程序猿!";
System.out.println("加密前的数据:\r\n" + source);
System.out.println("--------------------------公钥加密,私钥解密------------------------------");
// 公钥加密
String target = encryptionByPublicKey(source);
// 私钥解密
decryptionByPrivateKey(target);
System.out.println("--------------------------私钥加密并且签名,公钥验证签名并且解密------------------------------");
// 私钥加密
target = encryptionByPrivateKey(source);
// 签名
String sign = signByPrivateKey(target);
// 验证签名
verifyByPublicKey(target, sign);
// 公钥解密
decryptionByPublicKey(target);
}
**
* 生成密钥对
* @throws Exception
*
static void generatorKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(A);
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
byte[] keyBs = rsaPublicKey.getEncoded();
publicKey = encodeBase64(keyBs);
System.out.println("生成的公钥:\r\n" + publicKey);
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
keyBs = rsaPrivateKey.getEncoded();
privateKey = encodeBase64(keyBs);
System.out.println("生成的私钥:\r\n" + privateKey);
}
**
* 获取公钥
* @return
* @throws Exception
*
static PublicKey getPublicKey() throws Exception {
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(decodeBase64(publicKey));
KeyFactory keyFactory = KeyFactory.getInstance(A);
return keyFactory.generatePublic(publicKeySpec);
}
**
* 获取私钥
* @return
* @throws Exception
*
static PrivateKey getPrivateKey() throws Exception {
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(decodeBase64(privateKey));
KeyFactory keyFactory = KeyFactory.getInstance(A);
return keyFactory.generatePrivate(privateKeySpec);
}
**
* 公钥加密
* @param data
* @return
* @throws Exception
*
static String encryptionByPublicKey(String source) throws Exception{
PublicKey publicKey = getPublicKey();
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
cipher.update(source.getBytes("UTF-8"));
String target = encodeBase64(cipher.doFinal());
System.out.println("公钥加密后的数据:\r\n" + target);
return target;
}
**
* 公钥解密
* @param target
* @throws Exception
*
static void decryptionByPublicKey(String target) throws Exception{
PublicKey publicKey = getPublicKey();
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
cipher.update(decodeBase64(target));
String source = new String(cipher.doFinal(), "UTF-8");
System.out.println("公钥解密后的数据:\r\n" + source);
}
**
* 公钥验证签名
* @return
* @throws Exception
*
static void verifyByPublicKey(String target, String sign) throws Exception{
PublicKey publicKey = getPublicKey();
Signature signature = Signature.getInstance(B);
signature.initVerify(publicKey);
signature.update(target.getBytes("UTF-8"));
if (signature.verify(decodeBase64(sign))) {
System.out.println("签名正确!");
} else {
System.out.println("签名错误!");
}
}
**
* 私钥加密
* @param data
* @return
* @throws Exception
*
static String encryptionByPrivateKey(String source) throws Exception {
PrivateKey privateKey = getPrivateKey();
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
cipher.update(source.getBytes("UTF-8"));
String target = encodeBase64(cipher.doFinal());
System.out.println("私钥加密后的数据:\r\n" + target);
return target;
}
**
* 私钥解密
* @param target
* @throws Exception
*
static void decryptionByPrivateKey(String target) throws Exception {
PrivateKey privateKey = getPrivateKey();
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
cipher.update(decodeBase64(target));
String source = new String(cipher.doFinal(), "UTF-8");
System.out.println("私钥解密后的数据:\r\n" + source);
}
**
* 私钥签名
* @param target
* @return
* @throws Exception
*
static String signByPrivateKey(String target) throws Exception{
PrivateKey privateKey = getPrivateKey();
Signature signature = Signature.getInstance(B);
signature.initSign(privateKey);
signature.update(target.getBytes("UTF-8"));
String sign = encodeBase64(signature.sign());
System.out.println("生成的签名:\r\n" + sign);
return sign;
}
**
* base64编码
* @param source
* @return
* @throws Exception
*
static String encodeBase64(byte[] source) throws Exception{
return new String(Base64.encodeBase64(source), "UTF-8");
}
**
* Base64解码
* @param target
* @return
* @throws Exception
*
static byte[] decodeBase64(String target) throws Exception{
return Base64.decodeBase64(target.getBytes("UTF-8"));
}
}
结果:
生成的公钥:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC30e3AGr02d6WE96v2AC5N71C7y7Z8JptX3UfeqN57TZ1U3QsouvfchPxR6jzfeZxoe4oXQazB9fLkhdP6CNfSTv/rH8GItXdVc5iztDYMQahLfB7p9r34p5Z3Eitj2QeATcbqJnBulcUOQON7Nz1W5dkfo3MltaHxJ+ZrEGNF0QIDAQAB
生成的私钥:
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALfR7cAavTZ3pYT3q/YALk3vULvLtnwmm1fdR96o3ntNnVTdCyi699yE/FHqPN95nGh7ihdBrMH18uSF0/oI19JO/+sfwYi1d1VzmLO0NgxBqEt8Hun2vfinlncSK2PZB4BNxuomcG6VxQ5A43s3PVbl2R+jcyW1ofEn5msQY0XRAgMBAAECgYEAtkKzXvfkRl5JwtakLY2uW93/CcWKEf1hp7Qjb7W2q0GgzyVAzEjePEurtzju1JJLMBnWKQsYVVUdWdMMBG3CNvlXsAudPR1IK6GnoxkNsNEqfIlzMepEDiqwf1NOwOfsoSY0EyyX/Nka0zw8QN1zmQif1yAIWSF+5LeLx7FhCDECQQDhbBa4uVrqxTk0q2p/reA/5R1/lm/vqPB9HWQhwDXnP9O3fFrniLfdude+IHoV3ytbVDipSlEOsAR/mAfSuSQdAkEA0MEuVbNSF+AmJI7ZuCS2gy5z2Q3TwynQyq27FSS3+ViKlLv1t2PCM9jxL2fNTk8jd8tvI3rwf3hRzykgODSSRQJAUTWZce8Eu/NVSo4+jcTcNuiZme9eYB6ilNBT1HzkbmzmHwIj1anBY5WiDZKxqNN/USWkTAjD7uCmnjjtCJM+WQJARbDofhXihzP+p9/E0ZP4Fm1QoZrbImF4YeGD/ngGr0ie4y6oxnOYZuS7CB94S/dhmOGilc66MWQCs81AA2ORnQJACH9XEtcQxOyE47DjIqm/nNw8v+q+Slet7Us0sg5DkbwIZaICstyggXiEHNB6evyLhyA46Qw4Oz01n4VEwSlhuQ==
加密前的数据:
我是程序猿!
--------------------------公钥加密,私钥解密------------------------------
公钥加密后的数据:
e2rsWibl90o710/cYy/LRFF9+2gdZpNLv+lIFrU3covtzKCGNcUIcZdXEeyj8dtvIosZ6QvnYejZA0wclh6JcKURacaWcuzlVukezfuTILFEMkCVy1yHeyatxP6vRKj4xd3/pCVTo0LeOarF8LBe8XgbrokX08P9pN5G81CCsCI=
私钥解密后的数据:
我是程序猿!
--------------------------私钥加密并且签名,公钥验证签名并且解密------------------------------
私钥加密后的数据:
MypipFh/adDh5WOHJ8F6yK+DBJt4OpMhmIUWT3caWG4Cc3NFBtYMX58C5KfriDioBoKtr3wf4A3eb7PIl3dHShvX6QX3pz+II0qvqpLMS5v6iWSnJNarYC4JCZtDZRRpxSFuD8z0tjU7oH1ukUa/ymhZieA2l/hMHRPFY+jFp/E=
生成的签名:
SrW8TAN2alvuCX3R7YG0ir+ioPouWY6CKl4ojv6BursL21h+ZKSBvjI/HzmBQ+lvJgJR/MX/jwWCUbp8/J9yc02/4hWi5jvBcp6GAIrmprKf2gqQStyJ7v0oqnE9DQuToSc4dgiHL1PHbWdhZj/Q/UAVyDtyqrNSPxB9V+dzHSM=
签名正确!
公钥解密后的数据:
我是程序猿!
3,Blowfish
Blowfish是一个64位分组及可变密钥长度的分组密码算法,可用来加密64Bit长度的字符串。算法由两部分组成:密钥扩展和数据加密。密钥扩展把长度可达到448位的密钥转变成总共4168字节的几个子密钥。
demo:
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import org.apache.xmlbeans.impl.util.Base64;
public class Blowfish {
**
* @return
* @throws Exception
*
public static Key keyGenerator() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance("Blowfish");
keyGenerator.init(128);
return keyGenerator.generateKey();
}
**
* 加密
*
* @param key
* @param text
* @return
* @throws Exception
*
public static byte[] encrypt(Key key,String text) throws Exception {
Cipher cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(text.getBytes());
}
**
* 解密
*
* @param key
* @param text
* @return
* @throws Exception
*
public static byte[] decrypt(Key key,byte[] bt) throws Exception {
Cipher cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(bt);
}
**
* @param args
* @throws Exception
*
public static void main(String[] args) throws Exception {
Key key = keyGenerator();
System.out.println("Key : " + Base64.encode(key.getEncoded()));
String src = "123456";
byte[] target = encrypt(key, src);
System.out.println("密文: " + Base64.encode(target));
System.out.println("明文: " + new String(decrypt(key, target)));
}
}
结果:
Key : [B@f3d6a5
密文: [B@2a340e
明文: 123456
4,DES
(Data Encryption Standard)对称加密算法实现加密和解密Java对象。
demo:
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SealedObject;
import javax.crypto.SecretKey;
*
* @author xujie
* @date 2016-4-14
* @version 1.0.1
*
public class Test3 {
**
* @param args
* @throws Exception
*
public static void main(String args[]) throws Exception {
// Bouncy Castle 支持
//Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
// DES算法
SecretKey secretKey = KeyGenerator.getInstance("DES").generateKey();
// DES加密
Cipher encrypter = Cipher.getInstance("DES");
encrypter.init(Cipher.ENCRYPT_MODE, secretKey);
// DES解密
Cipher decrypter = Cipher.getInstance("DES");
decrypter.init(Cipher.DECRYPT_MODE, secretKey);
// 加密对象
// User user = new User("zhangsan","zs123456");
String user="123456";
// 把对象密在SealedObject中
SealedObject sealed = new SealedObject(user, encrypter);
System.out.println("加密对象:"+sealed);
// 解密对象
String algorithmName = sealed.getAlgorithm();
System.out.println("算法名称: " + algorithmName);
// 从密封中取出对象
String user2 = (String) sealed.getObject(decrypter);
System.out.println("密码: " + user2);
}
}
结果:
加密对象:javax.crypto.SealedObject@3e86d0
算法名称: DES
密码: 123456
5,其他
还有如凯撒加密
AES对称加密算法:
高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。
DESede对称加密算法:
DESede是由DES对称加密算法改进后的一种对称加密算法。使用 168 位的密钥对资料进行三次加密的一种机制。如果三个56位的子元素都相同,则三重 DES 向后兼容 DES。
DH加密算法:
Diffie-Hellman,一种确保共享KEY安全穿越不安全网络的方法,它是OAKLEY的一个组成部分。Whitefield与Martin Hellman在1976年提出了一个奇妙的密钥交换协议,称为Diffie-Hellman密钥交换协议/算法(Diffie-Hellman Key Exchange/Agreement Algorithm)。
RC4对称加密算法:
RC4加密算法是大名鼎鼎的RSA三人组中的头号人物Ronald Rivest在1987年设计的密钥长度可变的流加密算