加密算法

http://blog.csdn.net/qq_26685493/article/details/51179378

目前数据加密技术根据加密密钥类型可分为公私钥加密(对称加密)和公钥加密(非对称加密)两种。

1 对称加密(AES为例)

对称加密是通信双方在加/解密过程中使用它们共享的单一密钥,算法简单和加密速度快,是目前主流的密码体制之一。

最常用的对称加密算法是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);

2 非对称加密(RSA为例)

非对称加密是加/解密钥不同(公钥加密、私钥解密),密钥管理简单,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);

3 md5加密算法

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());

4 base64

使用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;  
    }  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值