本文介紹常見的算法(MD5/SHA,DSA,RSA,DES)的應用場景,以及在java上的使用方法.
1) MD5/SHA
MessageDigest是一個數(shù)據(jù)的數(shù)字指紋.即對一個任意長度的數(shù)據(jù)進行計算,產(chǎn)生一個唯一指紋號.
MessageDigest的特性:
A) 兩個不同的數(shù)據(jù),難以生成相同的指紋號
B) 對于指定的指紋號,難以逆向計算出原始數(shù)據(jù)
代表:MD5/SHA
Java實現(xiàn):
MD5:
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(Constant.DATA.getBytes());
byte[] result = md.digest();

SHA:
MessageDigest md = MessageDigest.getInstance("SHA");

md.update(Constant.DATA.getBytes());

byte[] result = md.digest();
2) DES
單密鑰算法,是信息的發(fā)送方采用密鑰A進行數(shù)據(jù)加密,信息的接收方采用同一個密鑰A進行數(shù)據(jù)解密.
單密鑰算法是一個對稱算法.
缺點:由于采用同一個密鑰進行加密解密,在多用戶的情況下,密鑰保管的安全性是一個問題.
代表:DES
Java實現(xiàn):
首先,需要生成一個密鑰,這邊的做法,是把生成的密鑰,保存到某個文件中.
KeyGenerator gen = KeyGenerator.getInstance("DES");
Key key = gen.generateKey();
File keyFile = new File(Constant.CRYPT_KEY_FILE);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(keyFile));
out.writeObject(key);
out.close();

在生成key的時候,可以通過SecureRandom產(chǎn)生一個可信任的隨機數(shù)源
KeyGenerator gen = KeyGenerator.getInstance("DES");
gen.init(new SecureRandom(seed));
Key key = gen.generateKey();
加密:
Key key = gen.getKey(Constant.CRYPT_KEY_FILE);//從文件中得到密鑰
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key); //指定是加密模式
cipher.update(Constant.DATA.getBytes());
byte[] result = cipher.doFinal();
解密:
由于DES是一個對稱算法,所以解密代碼跟加密代碼幾乎一致
key = gen.getKey(Constant.CRYPT_KEY_FILE);
cipher.init(Cipher.DECRYPT_MODE, key); //指定是解密模式
cipher.update(result);
byte[] data = cipher.doFinal();
由于采用了同一個密鑰(key),所以兩端代碼中
Constant.DATA.getBytes()和 data 的值是一致的.
3) DSA
所謂數(shù)字簽名是指發(fā)送方從發(fā)送報文中抽取特征數(shù)據(jù)(稱為數(shù)字指紋或摘要),然后用發(fā)送方的私鑰對數(shù)字指紋使用加密算法進行算法操作,接受方使用發(fā)送方已經(jīng)公開的公鑰解密并驗證報文.
數(shù)字簽名用戶驗證發(fā)送方身份或者發(fā)送方信息的完整性
代表:DSA
Java實現(xiàn):
同樣,首先需要生成一個公鑰和私鑰,我們也把它保存到相應的文件中
KeyPairGenerator gen = KeyPairGenerator.getInstance(“DSA”);

//以指定的長度初始化KeyPairGenerator對象,如果沒有初始化系統(tǒng)以1024長度默認設置

//參數(shù):keysize 算法位長.其范圍必須在 512 到 1024 之間,且必須為 64 的倍數(shù)

gen.initialize(1024);

KeyPair pair = gen.generateKeyPair();

File pubkeyFile = new File(Constant.PUB_KEY_FILE);

File prikeyFile = new File(Constant.PRI_KEY_FILE);

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(pubkeyFile));

out.writeObject(pair.getPublic());

out.close();

out = new ObjectOutputStream(new FileOutputStream(prikeyFile));

out.writeObject(pair.getPrivate());

out.close();

簽名:
PrivateKey prikey = (PrivateKey) gen.getKey(Constant.PRI_KEY_FILE); //從文件得到私鑰

// 用私鑰對數(shù)據(jù)簽名

Signature signature = Signature.getInstance("DSA");

signature.initSign(prikey);

signature.update(Constant.DATA.getBytes());

byte[] bytes = signature.sign();


把原始數(shù)據(jù)和簽名發(fā)送給接收方
驗證:
用公鑰對原始數(shù)據(jù)和簽名進行驗證
PublicKey pubkey = (PublicKey) gen.getKey(Constant.PUB_KEY_FILE);//從文件得到公鑰

Signature check = Signature.getInstance("DSA");

check.initVerify(pubkey);

check.update(Constant.DATA.getBytes());

//驗證數(shù)據(jù)的完整性


if (check.verify(bytes))
{

System.out.println("OK");


} else
{

System.out.println("ERROR");

}
4) RSA
公鑰密碼體制:為了解決單密鑰保管安全性的問題,提供了公鑰密碼體制的概念.在公鑰體制中,加密密鑰不同于解密密鑰,加密密鑰公之于眾,誰都可以使用;解密密鑰只有解密人自己知道。它們分別稱為公開密鑰(Public key)和秘密密鑰(Private key)。
代表:RSA
Java實現(xiàn):
同樣,需要生成公鑰和私鑰,并且保存到相應的文件中
KeyPairGenerator gen = KeyPairGenerator.getInstance(“RSA”);

//以指定的長度初始化KeyPairGenerator對象,如果沒有初始化系統(tǒng)以1024長度默認設置

//參數(shù):keysize 算法位長.其范圍必須在 512 到 1024 之間,且必須為 64 的倍數(shù)

gen.initialize(1024);

KeyPair pair = gen.generateKeyPair();

File pubkeyFile = new File(Constant.PUB_KEY_FILE);

File prikeyFile = new File(Constant.PRI_KEY_FILE);

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(pubkeyFile));

out.writeObject(pair.getPublic());

out.close();

out = new ObjectOutputStream(new FileOutputStream(prikeyFile));

out.writeObject(pair.getPrivate());

out.close();


加密:
采用公鑰進行加密:
PublicKey pubkey = (PublicKey) gen.getKey(Constant.PUB_KEY_FILE);//從文件中得到公鑰

Cipher cipher = Cipher.getInstance("RSA");

cipher.init(Cipher.ENCRYPT_MODE, pubkey);//指定加密模式

byte[] bytes = cipher.doFinal(Constant.DATA.getBytes());

解密:
采用私鑰進行解密:
PrivateKey prikey = (PrivateKey) gen.getKey(Constant.PRI_KEY_FILE);//從文件中得到私鑰

Cipher c = Cipher.getInstance("RSA");

c.init(Cipher.DECRYPT_MODE, prikey);//指定解密模式

byte[] data = c.doFinal(bytes);

兩段代碼中, Constant.DATA.getBytes()和data的值是一致的.
以上,對常見的算法,對了簡單的介紹.一般情況下,可以滿足我們日常的需求了.
附件是中java實現(xiàn)代碼:
java code