加密算法有不少種:這裏只大約列舉幾例:java
1:消息摘要:(數字指紋):既對一個任意長度的一個數據塊進行計算,產生一個惟一指紋。MD5/SHA1
發送給其餘人你的信息和摘要,其餘人用相同的加密方法獲得摘要,最後進行比較摘要是否相同。
2:單匙密碼體制:DES:比較簡便高效,密鑰簡短,加解密速度快,破譯極其困難,但其安全性依賴於密匙的安全性。
DES(Data Encryption Standard)是發明最先的最普遍使用的分組對稱加密算法。DES算法的入口參數有三個:Key、Data、Mode。其中Key爲8個字節共64位,是DES算法的工做密鑰;Data也爲8個字節64位,是要被加密或被解密的數據;Mode爲DES的工做方式,有兩種:加密或解密
3:數字簽名:就是信息發送者用其私鑰對從所傳報文中提取出的特徵數據(或稱數字指紋)進行RSA算法操做,以保證發信人沒法抵賴曾發過該信息(即不可抵賴性),同時也確保信息報文在經簽名後末被篡改(即完整性)。當信息接收者收到報文後,就能夠用發送者的公鑰對數字簽名進行驗證。
表明:DSA
4:非對稱密匙密碼體制(公匙體系):加密密匙不一樣於解密密匙,加密密匙公之於衆,誰均可以使用,解密密匙只有解密人本身知道。表明:RSA算法
下面是對上面幾個例子進行的簡單實現:數組
package test; 安全
import java.io.FileInputStream; 框架
import java.io.FileOutputStream; dom
import java.io.IOException; ide
import java.io.ObjectInputStream; 測試
import java.io.ObjectOutputStream; 編碼
import java.security.*; 加密
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
/**
* 加密解密
*
* @author shy.qiu
* @since http://blog.csdn.net/qiushyfm
*/
publicclass CryptTest {
/**
* 進行MD5加密
*
* @param info
* 要加密的信息
* @return String 加密後的字符串
*/
public String encryptToMD5(String info) {
byte[] digesta = null;
try {
// 獲得一個md5的消息摘要
MessageDigest alga = MessageDigest.getInstance("MD5");
// 添加要進行計算摘要的信息
alga.update(info.getBytes());
// 獲得該摘要
digesta = alga.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// 將摘要轉爲字符串
String rs = byte2hex(digesta);
return rs;
}
/**
* 進行SHA加密
*
* @param info
* 要加密的信息
* @return String 加密後的字符串
*/
public String encryptToSHA(String info) {
byte[] digesta = null;
try {
// 獲得一個SHA-1的消息摘要
MessageDigest alga = MessageDigest.getInstance("SHA-1");
// 添加要進行計算摘要的信息
alga.update(info.getBytes());
// 獲得該摘要
digesta = alga.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// 將摘要轉爲字符串
String rs = byte2hex(digesta);
return rs;
}
// //////////////////////////////////////////////////////////////////////////
/**
* 建立密匙
*
* @param algorithm
* 加密算法,可用 DES,DESede,Blowfish
* @return SecretKey 祕密(對稱)密鑰
*/
public SecretKey createSecretKey(String algorithm) {
// 聲明KeyGenerator對象
KeyGenerator keygen;
// 聲明 密鑰對象
SecretKey deskey = null;
try {
// 返回生成指定算法的祕密密鑰的 KeyGenerator 對象
keygen = KeyGenerator.getInstance(algorithm);
// 生成一個密鑰
deskey = keygen.generateKey();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// 返回密匙
return deskey;
}
/**
* 根據密匙進行DES加密
*
* @param key
* 密匙
* @param info
* 要加密的信息
* @return String 加密後的信息
*/
public String encryptToDES(SecretKey key, String info) {
// 定義 加密算法,可用 DES,DESede,Blowfish
String Algorithm = "DES";
// 加密隨機數生成器 (RNG),(能夠不寫)
SecureRandom sr = new SecureRandom();
// 定義要生成的密文
byte[] cipherByte = null;
try {
// 獲得加密/解密器
Cipher c1 = Cipher.getInstance(Algorithm);
// 用指定的密鑰和模式初始化Cipher對象
// 參數:(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)
c1.init(Cipher.ENCRYPT_MODE, key, sr);
// 對要加密的內容進行編碼處理,
cipherByte = c1.doFinal(info.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
// 返回密文的十六進制形式
return byte2hex(cipherByte);
}
/**
* 根據密匙進行DES解密
*
* @param key
* 密匙
* @param sInfo
* 要解密的密文
* @return String 返回解密後信息
*/
public String decryptByDES(SecretKey key, String sInfo) {
// 定義 加密算法,
String Algorithm = "DES";
// 加密隨機數生成器 (RNG)
SecureRandom sr = new SecureRandom();
byte[] cipherByte = null;
try {
// 獲得加密/解密器
Cipher c1 = Cipher.getInstance(Algorithm);
// 用指定的密鑰和模式初始化Cipher對象
c1.init(Cipher.DECRYPT_MODE, key, sr);
// 對要解密的內容進行編碼處理
cipherByte = c1.doFinal(hex2byte(sInfo));
} catch (Exception e) {
e.printStackTrace();
}
// return byte2hex(cipherByte);
returnnew String(cipherByte);
}
// /////////////////////////////////////////////////////////////////////////////
/**
* 建立密匙組,並將公匙,私匙放入到指定文件中
*
* 默認放入mykeys.bat文件中
*/
publicvoid createPairKey() {
try {
// 根據特定的算法一個密鑰對生成器
KeyPairGenerator keygen = KeyPairGenerator.getInstance("DSA");
// 加密隨機數生成器 (RNG)
SecureRandom random = new SecureRandom();
// 從新設置此隨機對象的種子
random.setSeed(1000);
// 使用給定的隨機源(和默認的參數集合)初始化肯定密鑰大小的密鑰對生成器
keygen.initialize(512, random);// keygen.initialize(512);
// 生成密鑰組
KeyPair keys = keygen.generateKeyPair();
// 獲得公匙
PublicKey pubkey = keys.getPublic();
// 獲得私匙
PrivateKey prikey = keys.getPrivate();
// 將公匙私匙寫入到文件當中
doObjToFile("mykeys.bat", new Object[] { prikey, pubkey });
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
/**
* 利用私匙對信息進行簽名 把簽名後的信息放入到指定的文件中
*
* @param info
* 要簽名的信息
* @param signfile
* 存入的文件
*/
publicvoid signToInfo(String info, String signfile) {
// 從文件當中讀取私匙
PrivateKey myprikey = (PrivateKey) getObjFromFile("mykeys.bat", 1);
// 從文件中讀取公匙
PublicKey mypubkey = (PublicKey) getObjFromFile("mykeys.bat", 2);
try {
// Signature 對象可用來生成和驗證數字簽名
Signature signet = Signature.getInstance("DSA");
// 初始化簽署簽名的私鑰
signet.initSign(myprikey);
// 更新要由字節簽名或驗證的數據
signet.update(info.getBytes());
// 簽署或驗證全部更新字節的簽名,返回簽名
byte[] signed = signet.sign();
// 將數字簽名,公匙,信息放入文件中
doObjToFile(signfile, new Object[] { signed, mypubkey, info });
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 讀取數字簽名文件 根據公匙,簽名,信息驗證信息的合法性
*
* @return true 驗證成功 false 驗證失敗
*/
publicboolean validateSign(String signfile) {
// 讀取公匙
PublicKey mypubkey = (PublicKey) getObjFromFile(signfile, 2);
// 讀取簽名
byte[] signed = (byte[]) getObjFromFile(signfile, 1);
// 讀取信息
String info = (String) getObjFromFile(signfile, 3);
try {
// 初始一個Signature對象,並用公鑰和簽名進行驗證
Signature signetcheck = Signature.getInstance("DSA");
// 初始化驗證簽名的公鑰
signetcheck.initVerify(mypubkey);
// 使用指定的 byte 數組更新要簽名或驗證的數據
signetcheck.update(info.getBytes());
System.out.println(info);
// 驗證傳入的簽名
return signetcheck.verify(signed);
} catch (Exception e) {
e.printStackTrace();
returnfalse;
}
}
/**
* 將二進制轉化爲16進制字符串
*
* @param b
* 二進制字節數組
* @return String
*/
public String byte2hex(byte[] b) {
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1) {
hs = hs + "0" + stmp;
} else {
hs = hs + stmp;
}
}
return hs.toUpperCase();
}
/**
* 十六進制字符串轉化爲2進制
*
* @param hex
* @return
*/
publicbyte[] hex2byte(String hex) {
byte[] ret = newbyte[8];
byte[] tmp = hex.getBytes();
for (int i = 0; i < 8; i++) {
ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
}
return ret;
}
/**
* 將兩個ASCII字符合成一個字節; 如:"EF"--> 0xEF
*
* @param src0
* byte
* @param src1
* byte
* @return byte
*/
publicstaticbyte uniteBytes(byte src0, byte src1) {
byte _b0 = Byte.decode("0x" + new String(newbyte[] { src0 }))
.byteValue();
_b0 = (byte) (_b0 << 4);
byte _b1 = Byte.decode("0x" + new String(newbyte[] { src1 }))
.byteValue();
byte ret = (byte) (_b0 ^ _b1);
return ret;
}
/**
* 將指定的對象寫入指定的文件
*
* @param file
* 指定寫入的文件
* @param objs
* 要寫入的對象
*/
publicvoid doObjToFile(String file, Object[] objs) {
ObjectOutputStream oos = null;
try {
FileOutputStream fos = new FileOutputStream(file);
oos = new ObjectOutputStream(fos);
for (int i = 0; i < objs.length; i++) {
oos.writeObject(objs[i]);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 返回在文件中指定位置的對象
*
* @param file
* 指定的文件
* @param i
* 從1開始
* @return
*/
public Object getObjFromFile(String file, int i) {
ObjectInputStream ois = null;
Object obj = null;
try {
FileInputStream fis = new FileInputStream(file);
ois = new ObjectInputStream(fis);
for (int j = 0; j < i; j++) {
obj = ois.readObject();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return obj;
}
/**
* 測試
*
* @param args
*/
publicstaticvoid main(String[] args) {
CryptTest jiami = new CryptTest();
// 執行MD5加密"Hello world!"
System.out.println("Hello通過MD5:" + jiami.encryptToMD5("Hello"));
// 生成一個DES算法的密匙
SecretKey key = jiami.createSecretKey("DES");
// 用密匙加密信息"Hello world!"
String str1 = jiami.encryptToDES(key, "Hello");
System.out.println("使用des加密信息Hello爲:" + str1);
// 使用這個密匙解密
String str2 = jiami.decryptByDES(key, str1);
System.out.println("解密後爲:" + str2);
// 建立公匙和私匙
jiami.createPairKey();
// 對Hello world!使用私匙進行簽名
jiami.signToInfo("Hello", "mysign.bat");
// 利用公匙對簽名進行驗證。
if (jiami.validateSign("mysign.bat")) {
System.out.println("Success!");
} else {
System.out.println("Fail!");
}
}
}
用到的重要的類
javax.crypto.KeyGenerator
public final SecretKey generateKey()生成一個密鑰
public static final KeyGenerator getInstance(String algorithm) 返回生成指定算法的祕密密鑰的KeyGenerator對象。
javax.crypto 接口 SecretKey
javax.crypto.Cipher 此類爲加密和解密提供密碼功能。它構成了 Java Cryptographic Extension (JCE) 框架的核心
public final void init(int opmode,Key key)
public final byte[] doFinal(byte[] input) 按單部分操做加密或解密數據,或者結束一個多部分操做
java.security.KeyPairGenerator
static KeyPairGenerator getInstance(String algorithm)
回生成指定算法的 public/private 密鑰對的 KeyPairGenerator 對象。
java.security.Signature
使用 Signature 對象簽名數據或驗證簽名包括如下三個階段:
1:初始化,使用
初始化驗證簽名的公鑰(請參見 initVerify),或使用
初始化簽署簽名的私鑰(也能夠選擇「安全隨機數生成器」)initSign(PrivateKey)和initSign(PrivateKey, SecureRandom))。
2:更新
根據初始化類型,這可更新要簽名或驗證的字節。請參見 update 方法。
3:簽署或驗證全部更新字節的簽名。請參見 sign 方法和 verify 方法。