本文介紹常見的算法(MD5/SHA,DSA,RSA,DES)的應(yīng)用場(chǎng)景,以及在java上的使用方法.
1) MD5/SHA
MessageDigest是一個(gè)數(shù)據(jù)的數(shù)字指紋.即對(duì)一個(gè)任意長(zhǎng)度的數(shù)據(jù)進(jìn)行計(jì)算,產(chǎn)生一個(gè)唯一指紋號(hào).
MessageDigest的特性:
A) 兩個(gè)不同的數(shù)據(jù),難以生成相同的指紋號(hào)
B) 對(duì)于指定的指紋號(hào),難以逆向計(jì)算出原始數(shù)據(jù)
代表:MD5/SHA
Java實(shí)現(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進(jìn)行數(shù)據(jù)加密,信息的接收方采用同一個(gè)密鑰A進(jìn)行數(shù)據(jù)解密.
單密鑰算法是一個(gè)對(duì)稱算法.
缺點(diǎn):由于采用同一個(gè)密鑰進(jìn)行加密解密,在多用戶的情況下,密鑰保管的安全性是一個(gè)問(wèn)題.
代表:DES
Java實(shí)現(xiàn):
首先,需要生成一個(gè)密鑰,這邊的做法,是把生成的密鑰,保存到某個(gè)文件中.
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的時(shí)候,可以通過(guò)SecureRandom產(chǎn)生一個(gè)可信任的隨機(jī)數(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是一個(gè)對(duì)稱算法,所以解密代碼跟加密代碼幾乎一致
key = gen.getKey(Constant.CRYPT_KEY_FILE);
cipher.init(Cipher.DECRYPT_MODE, key); //指定是解密模式
cipher.update(result);
byte[] data = cipher.doFinal();
由于采用了同一個(gè)密鑰(key),所以兩端代碼中
Constant.DATA.getBytes()和 data 的值是一致的.
3) DSA
所謂數(shù)字簽名是指發(fā)送方從發(fā)送報(bào)文中抽取特征數(shù)據(jù)(稱為數(shù)字指紋或摘要),然后用發(fā)送方的私鑰對(duì)數(shù)字指紋使用加密算法進(jìn)行算法操作,接受方使用發(fā)送方已經(jīng)公開的公鑰解密并驗(yàn)證報(bào)文.
數(shù)字簽名用戶驗(yàn)證發(fā)送方身份或者發(fā)送方信息的完整性
代表:DSA
Java實(shí)現(xiàn):
同樣,首先需要生成一個(gè)公鑰和私鑰,我們也把它保存到相應(yīng)的文件中
KeyPairGenerator gen = KeyPairGenerator.getInstance(“DSA”);

//以指定的長(zhǎng)度初始化KeyPairGenerator對(duì)象,如果沒(méi)有初始化系統(tǒng)以1024長(zhǎng)度默認(rèn)設(shè)置

//參數(shù):keysize 算法位長(zhǎng).其范圍必須在 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); //從文件得到私鑰

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

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

signature.initSign(prikey);

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

byte[] bytes = signature.sign();


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

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

check.initVerify(pubkey);

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

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


if (check.verify(bytes))
{

System.out.println("OK");


} else
{

System.out.println("ERROR");

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

//以指定的長(zhǎng)度初始化KeyPairGenerator對(duì)象,如果沒(méi)有初始化系統(tǒng)以1024長(zhǎng)度默認(rèn)設(shè)置

//參數(shù):keysize 算法位長(zhǎng).其范圍必須在 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();


加密:
采用公鑰進(jìn)行加密:
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());

解密:
采用私鑰進(jìn)行解密:
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的值是一致的.
以上,對(duì)常見的算法,對(duì)了簡(jiǎn)單的介紹.一般情況下,可以滿足我們?nèi)粘5男枨罅?/span>.
附件是中java實(shí)現(xiàn)代碼:
java code