本文主要介绍Java加密框架(JCA,Java Cryptography Architecture)。Java加密框架主要由java.security和javax.crypto两个包下的API提供服务。
3 加密实践
3.1 消息摘要
使用SHA-256算法计算消息原文plainData的消息摘要。
/**
* 生成消息摘要
*
* @param plainData
* @return
*/
public static byte[] generateMessageDigest(byte[] plainData) {
byte[] digest = null;
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
digest = messageDigest.digest(plainData);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return digest;
}
3.2 MAC
如前所述,MAC需要对称加密密钥,生成方法如下:
/**
* 生成SecretKeySpec
*
* @return
*/
public static SecretKeySpec generateSecretKeySpec() {
byte[] keyBytes = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
String algorithm = "RawBytes";
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, algorithm);
return secretKeySpec;
}
使用HmacSHA256算法计算消息原文plainData的MAC消息摘要
/**
* 生成MAC摘要
*
* @param plainData
* @return
*/
public static byte[] generateMacDigest(byte[] plainData) {
byte[] macBytes = null;
try {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec key = KeyUtil.generateSecretKeySpec();
mac.init(key);
macBytes = mac.doFinal(plainData);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return macBytes;
}
3.3 数字签名
如前所述,数字签名需要公私密钥对,生成方法如下:
/**
* 生成KeyPair
*
* @return
*/
public static KeyPair generateKeyPair(String algorithm) {
KeyPair keyPair = null;
try {
if (algorithm == null || algorithm.isEmpty()) {
algorithm = "DSA";
}
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
keyPair = keyPairGenerator.generateKeyPair();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return keyPair;
}
使用算法SHA1withRSA和密钥对keyPair计算消息原文plainData的数字签名
/**
* 生成数字签名(即用私钥加密的消息摘要)
*
* @param plainData
* @return
*/
public static byte[] generateDigitalSignature(byte[] plainData, KeyPair keyPair) {
byte[] signatureData = null;
try {
Signature signature = Signature.getInstance("SHA1withRSA");
SecureRandom secureRandom = new SecureRandom();
signature.initSign(keyPair.getPrivate(), secureRandom);
signature.update(plainData);
signatureData