http://blog.csdn.net/qq_26685493/article/details/51179378
目前数据加密技术根据加密密钥类型可分为公私钥加密(对称加密)和公钥加密(非对称加密)两种。
对称加密是通信双方在加/解密过程中使用它们共享的单一密钥,算法简单和加密速度快,是目前主流的密码体制之一。
最常用的对称加密算法是DES(数据加密标准)算法,但由于DES密钥长度较短,现在由AES(对称高级数据加密标准)取代。 AES的加密算法的数据处理单位是字节,128位的比特信息被分成16个字节,按顺序复制到一个4*4的矩阵中,成为状态,AES的所有变换都是基于状态 矩阵的变换。
DES加密解密步骤:
生成一个长度至少大于8位的字符串作为工作密钥,会使用该密钥作为加密和解密的操作 DESKeySpec keySpec = new DESKeySpec(key.getBytes()); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("des"); SecretKey secretKey = keyFactory.generateSecret(keySpec); 加密 Cipher cipher = Cipher.getInstance("des"); cipher.init(Cipher.ENCRYPT_MODE, secretKey, new SecureRandom()); byte[] cipherData = cipher.doFinal(plainText.getBytes()); 解密 cipher.init(Cipher.DECRYPT_MODE, secretKey, new SecureRandom()); byte[] plainData = cipher.doFinal(cipherData); String plainText = new String(plainData);非对称加密是加/解密钥不同(公钥加密、私钥解密),密钥管理简单,RSA是非对称加密最著名的公钥密码算法。
RSA算法是基于大质数的因数分解的公钥体系,简单讲,就是两个很大的质数,一个作为公钥,另一个作为私钥,如用其中一个加密,则用另一个解密。 密钥长度从40到2048位可变,密钥越长,加密效果越好,但加密解密的开销也大
RSA加密解密步骤:
服务器发送数据给客户端时使用私钥加密,并且使用加密之后的数据和私钥生成数字签名并发送给客户端
客户端接收到服务器发送的数据会使用公钥对数据进行解密,并且根据加密数据和公钥验证数字签名的有效性,防止加密数据在传输过程中被 第三方进行修改
客户端发送数据给服务器使用公钥进行加密,服务器接收到加密数据之后使用私钥进行解密
创建密钥:
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("rsa"); keyPairGenerator.initialize(1024); // 密钥推荐长度2014位 KeyPair keyPair = keyPairGenerator.generateKeyPair(); PublicKey publicKey = keyPair.getPublic(); // 公钥 PrivateKey privatekey = keyPair.getPrivate(); // 私钥 // 服务器使用私钥加密 Cipher cipher = Cipher.getInstance("rsa"); cipher.init(Cipher.ENCRYPT_MODE, privateKey, new SecureRandom()); byte[] cipherData = cipher.doFinal(plainText.getBytes()); // 客户端公钥解密 cipher.init(Cipher.DECRYPT_MODE, publicKey, new SecureRandom()); byte[] plainData = cipher.doFinal(cipherData); // 服务器根据私钥加密数据生成数字签名 Signature signature = Signature.getInstance("MD5withRSA"); signature.initSign(privateKey); signature.update(cipherData); byte[] signData = signature.sign(); // 客户端根据公钥、加密数据验证是否被修改过 signature.initVerify(publicKey); signature.update(cipherData); boolean status = signature.verify(signData);md5加密算法是一种单向加密算法,只能加密,无法解密。
md5加密步骤:
将其中的每个字节转成十六进制:byye类型的数据最高位是符号位,通过和0xff进行与操作,转换为int类型的正整数
如果该正数小于16(长度为1个字符),前面拼接0占位;确保最后生成的是32为字符串
String plainText = "Hello world"; MessageDigest md5 = MessageDigest.getInstance("md5"); byte[] cipherData = md5.digest(plainText.getBytes()); StringBuilder builder = new StringBuilder(); for (byte cipher : ciperData) { String toHexStr = Integer.toHexString(cipher & 0xff); builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr); } System.out.println(builder.toString());使用base64算法通常用作对二进制数据进行加密,加密之后的数据不易被肉眼识别。严格来说,经过base64加密的数据其实没有安全性可保密,因为它的加密解密算法都是公开的。经过标准的base64算法加密后的数据,通常包含/、+、=等特殊符号,不适合作为url参数传递。
base64加密解密步骤:
加密 BASE64Encoder encoder = new BASE64Encoder(); String cipherText = encoder.encode(plainText.getBytes()); // 加密 解密 BASE64Decoder decoder = new BASE64Decoder(); plainText = new String(decoder.decodeBuffer(cipherText));工具类
package com.excelsoft.common.crypto; import java.io.IOException; import java.security.Key; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; /** * 功能简述: 加密解密工具类,对MD5/BASE64/DES/RSA等算法提供了包装. * @author Nick Xu * @version 1.0 */ public class EncryptUtil { private static Log logger = LogFactory.getLog(EncryptUtil.class); private static final int KEY_SIZE = 1024; private static final String MD5_ALGORITHM= "md5"; private static final String DES_ALGORITHM= "des"; private static final String RSA_ALGORITHM= "rsa"; private static final String SIGNATURE_ALGORITHM= "MD5withRSA"; private static MessageDigest md5; private static BASE64Encoder encoder; private static BASE64Decoder decoder; private static SecureRandom random; private static KeyPair keyPair; private EncryptUtil() { } static { try { md5 = MessageDigest.getInstance(MD5_ALGORITHM); KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA_ALGORITHM); keyPairGenerator.initialize(KEY_SIZE); keyPair = keyPairGenerator.generateKeyPair(); } catch (NoSuchAlgorithmException e) { // Exception handler logger.error(e); } encoder = new BASE64Encoder(); decoder = new BASE64Decoder(); random = new SecureRandom(); } /** * 功能简述: 使用md5进行单向加密. */ public static String encryptMD5(String plainText) { byte[] cipherData = md5.digest(plainText.getBytes()); StringBuilder builder = new StringBuilder(); for(byte cipher : cipherData) { String toHexStr = Integer.toHexString(cipher & 0xff); builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr); } return builder.toString(); } /** * 功能简述: 使用BASE64进行加密. * @param plainData 明文数据 * @return 加密之后的文本内容 */ public static String encryptBASE64(byte[] plainData) { return encoder.encode(plainData); } /** * 功能简述: 使用BASE64进行解密. * @param cipherText 密文文本 * @return 解密之后的数据 */ public static byte[] decryptBASE64(String cipherText) { byte[] plainData = null; try { plainData = decoder.decodeBuffer(cipherText); } catch (IOException e) { // Exception handler logger.error(e); } return plainData; } /** * 功能简述: 使用DES算法进行加密. * @param plainData 明文数据 * @param key 加密密钥 * @return */ public static byte[] encryptDES(byte[] plainData, String key) { return processCipher(plainData, createSecretKey(key), Cipher.ENCRYPT_MODE, DES_ALGORITHM); } /** * 功能简述: 使用DES算法进行解密. * @param cipherData 密文数据 * @param key 解密密钥 * @return */ public static byte[] decryptDES(byte[] cipherData, String key) { return processCipher(cipherData, createSecretKey(key), Cipher.DECRYPT_MODE, DES_ALGORITHM); } /** * 功能简述: 根据key创建密钥SecretKey. * @param key * @return */ private static SecretKey createSecretKey(String key) { SecretKey secretKey = null; try { DESKeySpec keySpec = new DESKeySpec(key.getBytes()); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM); secretKey = keyFactory.generateSecret(keySpec); } catch (Exception e) { // Exception handler logger.error(e); } return secretKey; } /** * 功能简述: 加密/解密处理流程. * @param processData 待处理的数据 * @param key 提供的密钥 * @param opsMode 工作模式 * @param algorithm 使用的算法 * @return */ private static byte[] processCipher(byte[] processData, Key key, int opsMode, String algorithm) { try{ Cipher cipher = Cipher.getInstance(algorithm); cipher.init(opsMode, key, random); return cipher.doFinal(processData); } catch (Exception e) { // Exception handler logger.error(e); } return null; } /** * 功能简述: 创建私钥,用于RSA非对称加密. * @return */ public static PrivateKey createPrivateKey() { return keyPair.getPrivate(); } /** * 功能简述: 创建公钥,用于RSA非对称加密. * @return */ public static PublicKey createPublicKey() { return keyPair.getPublic(); } /** * 功能简述: 使用RSA算法加密. * @param plainData 明文数据 * @param key 密钥 * @return */ public static byte[] encryptRSA(byte[] plainData, Key key) { return processCipher(plainData, key, Cipher.ENCRYPT_MODE, RSA_ALGORITHM); } /** * 功能简述: 使用RSA算法解密. * @param cipherData 密文数据 * @param key 密钥 * @return */ public static byte[] decryptRSA(byte[] cipherData, Key key) { return processCipher(cipherData, key, Cipher.DECRYPT_MODE, RSA_ALGORITHM); } /** * 功能简述: 使用私钥对加密数据创建数字签名. * @param cipherData 已经加密过的数据 * @param privateKey 私钥 * @return */ public static byte[] createSignature(byte[] cipherData, PrivateKey privateKey) { try { Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateKey); signature.update(cipherData); return signature.sign(); } catch (Exception e) { // Exception handler logger.error(e); } return null; } /** * 功能简述: 使用公钥对数字签名进行验证. * @param signData 数字签名 * @param publicKey 公钥 * @return */ public static boolean verifySignature(byte[] cipherData, byte[] signData, PublicKey publicKey) { try { Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(publicKey); signature.update(cipherData); return signature.verify(signData); } catch (Exception e) { // Exception handler logger.error(e); } return false; } }