3DES加密为对称加密算法,在Java实现中3DES的默认加密方式为ECB,默认填充方式为PKCS5Padding。密钥由服务方提供给客户方,即加解密都使用同一个密钥,所以只要有一方暴露了密钥就会存在安全问题。
RSA为非对称加密,需要有一对密钥,分别为公钥和私钥。如果使用者加解密过程,使用私钥加密,公钥解密;或者使用公钥加密,私钥解密。如果使用在签名和验签过程,则使用私钥签名,公钥验签;或者公钥签名,私钥验签。这样保证了只有一方暴露了密钥,不会产生安全威胁。
3DES加解密、DES加解密与RSA签名验签的Java实现:
public class EncryptUtil {
private static final String CHAR_SET_UTF8 = "UTF-8";
private static final String ALGORITHM_3DES = "DESede";
private static final String ALGORITHM_3DES_PADDING = "DESede/ECB/PKCS5Padding";
private static final String ALGORITHM_DES = "DES";
private static final String ALGORITHM_MD5_WITH_RSA = "MD5withRSA";
private static final String ALGORITHM_RSA = "RSA";
/**
* 3DES加密
*
* @param content 加密内容
* @param key 密钥
* @return
*/
public static String tripleDESEncrypt(String content, byte[] key) {
try {
// 根据key转换为对应的SecretKey对象
DESedeKeySpec spec = new DESedeKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM_3DES);
SecretKey tripleDesKey = keyFactory.generateSecret(spec);
// 初始化为加密模式的密码器
Cipher cipher = Cipher.getInstance(ALGORITHM_3DES_PADDING);
cipher.init(Cipher.ENCRYPT_MODE, tripleDesKey);
// 加密
byte[] result = cipher.doFinal(content.getBytes(CHAR_SET_UTF8));
// 通过Base64转码返回
return Base64.encodeBase64String(result);
} catch (Exception e) {
log.error("3DES加密失败!", e);
throw new BusinessException("3DES加密失败!", e);
}
}
/**
* 3DES解密
*
* @param content 解密内容
* @param key 密钥
* @return
*/
public static String tripleDESDecrypt(byte[] content, byte[] key) {
try {
// 根据key转换为对应的SecretKey对象
DESedeKeySpec spec = new DESedeKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM_3DES);
SecretKey tripleDesKey = keyFactory.generateSecret(spec);
// 实例化 使用密钥初始化,设置为解密模式
Cipher cipher = Cipher.getInstance(ALGORITHM_3DES_PADDING);
// 执行操作
cipher.init(Cipher.DECRYPT_MODE, tripleDesKey);
byte[] result = cipher.doFinal(content);
return new String(result);
} catch (Exception e) {
log.error("3DES解密失败额!", e);
throw new BusinessException("3DES解密失败!", e);
}
}
/**
* DES加密
*
* @param byteContent 加密内容
* @param key 密钥
* @return
*/
public static byte[] desEncrypt(byte[] byteContent, byte[] key) {
try {
// 根据key转换为对应的SecretKey对象
DESKeySpec desKeySpec = new DESKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM_DES);
SecretKey desKey = keyFactory.generateSecret(desKeySpec);
// 初始化为加密模式的密码器
Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
cipher.init(Cipher.ENCRYPT_MODE, desKey);
// 加密
byte[] result = cipher.doFinal(byteContent);
return result;
} catch (Exception e) {
log.error("3DES加密失败!", e);
throw new BusinessException("3DES加密失败!", e);
}
}
/**
* DES解密
*
* @param byteContent 加密内容
* @param key 密钥
* @return
*/
public static byte[] desDecrypt(byte[] byteContent, byte[] key) {
try {
// 根据key转换为对应的SecretKey对象
DESKeySpec desKeySpec = new DESKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM_DES);
SecretKey desKey = keyFactory.generateSecret(desKeySpec);
// 初始化为加密模式的密码器
Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
cipher.init(Cipher.DECRYPT_MODE, desKey);
// 解密
byte[] result = cipher.doFinal(byteContent);
return result;
} catch (Exception e) {
log.error("des解密失败!", e);
throw new BusinessException("des解密失败!", e);
}
}
/**
* 生成MD5WithRSA数字签名
*
* @param content 需要发送的报文内容
* @param privateKey 私钥
* @return
* @throws Exception
*/
public static String generateMD5WithRSASign(String content, String privateKey) {
try {
// 生成私钥对象
KeyFactory factory = KeyFactory.getInstance(ALGORITHM_RSA);
byte[] keyBytes2 = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes2);
PrivateKey key = factory.generatePrivate(pkcs8EncodedKeySpec);
byte[] contentBytes = content.getBytes(CHAR_SET_UTF8);
// 返回MD5withRSA签名算法的 Signature对象
Signature signature = Signature.getInstance(ALGORITHM_MD5_WITH_RSA);
signature.initSign(key);
signature.update(contentBytes);
byte[] signs = signature.sign();
return Base64.encodeBase64String(signs);
} catch (Exception e) {
log.error("生成数字签名异常!", e);
throw new BusinessException("生成数字签名异常!", e);
}
}
/**
* 验证MD5WithRSA数字签名
*
* @param content 接收到的报文内容
* @param sign 接收到的数字签名
* @param publicKey 公钥
* @return
* @throws Exception
*/
public static boolean verifyMD5WithRSASign(String content, byte[] sign, String publicKey) {
try {
// 生成公钥对象
byte[] keyBytes = Base64.decodeBase64(publicKey);
KeyFactory factory = KeyFactory.getInstance(ALGORITHM_RSA);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
PublicKey pubKey = factory.generatePublic(spec);
// 对用md5和RSA私钥生成的数字签名进行验证
byte[] contentBytes = content.getBytes(CHAR_SET_UTF8);
Signature signature = Signature.getInstance(ALGORITHM_MD5_WITH_RSA);
signature.initVerify(pubKey);
signature.update(contentBytes);
return signature.verify(sign);
} catch (Exception e) {
log.error("验证数字签名异常!", e);
throw new BusinessException("验证数字签名异常!", e);
}
}
/**
* 生成文件MD5摘要
*
* @param file 文件
* @return
*/
public String generateFileMD5(File file) {
FileInputStream inputStream = null;
String md5Message = null;
try {
inputStream = new FileInputStream(file);
md5Message = DigestUtils.md5Hex(inputStream);
return md5Message;
} catch (Exception e) {
log.error("文件MD5异常!", e);
throw new BusinessException("文件MD5异常!", e);
}
}
/**
* 生成密钥对,生成过后如果没有特殊情况不需要重新申请
*
* @return
* @throws Exception
*/
public static Map<String,String> generateKeyPair() {
KeyPairGenerator keyGen = null;
Map<String,String> keyMap = new HashMap<>();
try {
keyGen = KeyPairGenerator.getInstance(ALGORITHM_RSA);
// 秘钥长度
keyGen.initialize(1024);
KeyPair keyPair = keyGen.generateKeyPair();
PrivateKey aPrivate = keyPair.getPrivate();
String privateKey = Base64.encodeBase64String(aPrivate.getEncoded());
PublicKey aPublic = keyPair.getPublic();
String publicKey = Base64.encodeBase64String(aPublic.getEncoded());
keyMap.put("privateKey",privateKey);
keyMap.put("publicKey",publicKey);
return keyMap;
} catch (NoSuchAlgorithmException e) {
throw new BusinessException("生成密钥对异常!", e);
}
}
}
探索不以困难而止,学习不以艰苦而终
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。