码迷,mamicode.com
首页 > 编程语言 > 详细

【Java安全技术探索之路系列:Java可扩展安全架构】之七:JCE(三):JCE编程模型

时间:2015-06-15 18:46:26      阅读:280      评论:0      收藏:0      [点我收藏+]

标签:jce-编程模型   加密   解密   架构   

作者:郭嘉
邮箱:allenwells@163.com
博客:http://blog.csdn.net/allenwells
github:https://github.com/AllenWell

一 加密和解密

加密是一种打乱消息、文件或程序的加密技术。JCE基本的加密和解密流程如下所示:

  1. 生成密钥
  2. 创建Cipher对象
  3. 为加密而初始化Cipher对象
  4. 为解密而初始化Cipher对象

举例:DES算法加解密

package com.allenwells.jce;

import java.security.Key;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

/**
 * DES安全编码组件
 * 
 * @author AllenWells
 * @version 1.0
 */
public abstract class DESEncryptor
{

    /**
     * 密钥算法 <br>
     * Java 6 只支持56bit密钥 <br>
     * Bouncy Castle 支持64bit密钥
     */
    public static final String KEY_ALGORITHM = "DES";

    /**
     * 加密/解密算法 / 工作模式 / 填充方式
     */
    public static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5PADDING";

    /**
     * 转换密钥
     * 
     * @param key
     *            二进制密钥
     * @return Key 密钥
     * @throws Exception
     */
    private static Key toKey(byte[] key) throws Exception
    {

        // 实例化DES密钥材料
        DESKeySpec dks = new DESKeySpec(key);

        // 实例化秘密密钥工厂
        SecretKeyFactory keyFactory = SecretKeyFactory
                .getInstance(KEY_ALGORITHM);

        // 生成秘密密钥
        SecretKey secretKey = keyFactory.generateSecret(dks);

        return secretKey;
    }

    /**
     * 解密
     * 
     * @param data
     *            待解密数据
     * @param key
     *            密钥
     * @return byte[] 解密数据
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, byte[] key) throws Exception
    {

        // 还原密钥
        Key k = toKey(key);

        // 实例化
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

        // 初始化,设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, k);

        // 执行操作
        return cipher.doFinal(data);
    }

    /**
     * 加密
     * 
     * @param data
     *            待加密数据
     * @param key
     *            密钥
     * @return byte[] 加密数据
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, byte[] key) throws Exception
    {

        // 还原密钥
        Key k = toKey(key);

        // 实例化
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);

        // 初始化,设置为加密模式
        cipher.init(Cipher.ENCRYPT_MODE, k);

        // 执行操作
        return cipher.doFinal(data);
    }

    /**
     * 生成密钥 <br>
     * Java 6 只支持56bit密钥 <br>
     * Bouncy Castle 支持64bit密钥 <br>
     * 
     * @return byte[] 二进制密钥
     * @throws Exception
     */
    public static byte[] initKey() throws Exception
    {

        /*
         * 实例化密钥生成器
         * 
         * 若要使用64bit密钥注意替换 将下述代码中的KeyGenerator.getInstance(CIPHER_ALGORITHM);
         * 替换为KeyGenerator.getInstance(CIPHER_ALGORITHM, "BC");
         */
        KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);

        /*
         * 初始化密钥生成器 若要使用64bit密钥注意替换 将下述代码kg.init(56); 替换为kg.init(64);
         */
        kg.init(56, new SecureRandom());

        // 生成秘密密钥
        SecretKey secretKey = kg.generateKey();

        // 获得密钥的二进制编码形式
        return secretKey.getEncoded();
    }
}

二 封装对象

三 基于密码的加密

基于密码的加密(PBE)是一种根据密码推导加密密钥的技术,有助于攻击者发起的字典攻击及其他相关威胁。

举例:PBE加解密

package com.allenwells.jce;

import java.security.Key;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

/**
 * PBE安全编码组件
 * 
 * @author AllenWells
 * @version 1.0
 */
public abstract class PBEEncryptor
{
    /**
     * Java 6 支持以下任意一种算法
     * 
     * <pre>
     * PBEWithMD5AndDES 
     * PBEWithMD5AndTripleDES 
     * PBEWithSHA1AndDESede
     * PBEWithSHA1AndRC2_40
     * </pre>
     */
    public static final String ALGORITHM = "PBEWithMD5AndTripleDES";

    /**
     * 盐初始化<br>
     * 盐长度必须为8字节
     * 
     * @return byte[] 盐
     * @throws Exception
     */
    public static byte[] initSalt() throws Exception
    {

        SecureRandom random = new SecureRandom();

        return random.generateSeed(8);
    }

    /**
     * 转换密钥
     * 
     * @param password
     *            密码
     * @return Key 密钥
     * @throws Exception
     */
    private static Key toKey(String password) throws Exception
    {

        // 密钥材料转换
        PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());

        // 实例化
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);

        // 生成密钥
        SecretKey secretKey = keyFactory.generateSecret(keySpec);

        return secretKey;
    }

    /**
     * 加密
     * 
     * @param data
     *            数据
     * @param password
     *            密码
     * @param salt
     *            盐
     * @return byte[] 加密数据
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, String password, byte[] salt)
            throws Exception
    {

        // 转换密钥
        Key key = toKey(password);

        // 实例化PBE参数材料
        PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);

        // 实例化
        Cipher cipher = Cipher.getInstance(ALGORITHM);

        // 初始化
        cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);

        // 执行操作
        return cipher.doFinal(data);

    }

    /**
     * 解密
     * 
     * @param data
     *            数据
     * @param password
     *            密码
     * @param salt
     *            盐
     * @return byte[] 解密数据
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, String password, byte[] salt)
            throws Exception
    {

        // 转换密钥
        Key key = toKey(password);

        // 实例化PBE参数材料
        PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);

        // 实例化
        Cipher cipher = Cipher.getInstance(ALGORITHM);

        // 初始化
        cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);

        // 执行操作
        return cipher.doFinal(data);

    }
}

四 计算消息验证码对象

消息验证码通常用于根据密钥检查信息的完整性和有效性。

举例:MAC算法实现

package com.allenwells.jce;

import java.security.Security;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;

/**
 * MAC消息摘要组件
 * 
 * @author 梁栋
 * @version 1.0
 * @since 1.0
 */
public abstract class MACEncryptor
{

    /**
     * 初始化HmacMD2密钥
     * 
     * @return byte[] 密钥
     * @throws Exception
     */
    public static byte[] initHmacMD2Key() throws Exception
    {

        // 加入BouncyCastleProvider支持
        Security.addProvider(new BouncyCastleProvider());

        // 初始化KeyGenerator
        KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD2");

        // 产生秘密密钥
        SecretKey secretKey = keyGenerator.generateKey();

        // 获得密钥
        return secretKey.getEncoded();
    }

    /**
     * HmacMD2消息摘要
     * 
     * @param data
     *            待做消息摘要处理的数据
     * @param byte[] 密钥
     * @return byte[] 消息摘要
     * @throws Exception
     */
    public static byte[] encodeHmacMD2(byte[] data, byte[] key)
            throws Exception
    {

        // 加入BouncyCastleProvider支持
        Security.addProvider(new BouncyCastleProvider());

        // 还原密钥
        SecretKey secretKey = new SecretKeySpec(key, "HmacMD2");

        // 实例化Mac
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());

        // 初始化Mac
        mac.init(secretKey);

        // 执行消息摘要
        return mac.doFinal(data);
    }

    /**
     * HmacMD2Hex消息摘要
     * 
     * @param data
     *            待做消息摘要处理的数据
     * @param String
     *            密钥
     * @return byte[] 消息摘要
     * @throws Exception
     */
    public static String encodeHmacMD2Hex(byte[] data, byte[] key)
            throws Exception
    {

        // 执行消息摘要
        byte[] b = encodeHmacMD2(data, key);

        // 做十六进制转换
        return new String(Hex.encode(b));
    }

    /**
     * 初始化HmacMD4密钥
     * 
     * @return byte[] 密钥
     * @throws Exception
     */
    public static byte[] initHmacMD4Key() throws Exception
    {

        // 加入BouncyCastleProvider支持
        Security.addProvider(new BouncyCastleProvider());

        // 初始化KeyGenerator
        KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD4");

        // 产生秘密密钥
        SecretKey secretKey = keyGenerator.generateKey();

        // 获得密钥
        return secretKey.getEncoded();
    }

    /**
     * HmacMD4消息摘要
     * 
     * @param data
     *            待做消息摘要处理的数据
     * @param byte[] 密钥
     * @return byte[] 消息摘要
     * @throws Exception
     */
    public static byte[] encodeHmacMD4(byte[] data, byte[] key)
            throws Exception
    {

        // 加入BouncyCastleProvider支持
        Security.addProvider(new BouncyCastleProvider());

        // 还原密钥
        SecretKey secretKey = new SecretKeySpec(key, "HmacMD4");

        // 实例化Mac
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());

        // 初始化Mac
        mac.init(secretKey);

        // 执行消息摘要
        return mac.doFinal(data);
    }

    /**
     * HmacMD4Hex消息摘要
     * 
     * @param data
     *            待做消息摘要处理的数据
     * @param byte[] 密钥
     * @return String 消息摘要
     * @throws Exception
     */
    public static String encodeHmacMD4Hex(byte[] data, byte[] key)
            throws Exception
    {

        // 执行消息摘要
        byte[] b = encodeHmacMD4(data, key);

        // 做十六进制转换
        return new String(Hex.encode(b));
    }

    /**
     * 初始化HmacSHA224密钥
     * 
     * @return byte[] 密钥
     * @throws Exception
     */
    public static byte[] initHmacSHA224Key() throws Exception
    {

        // 加入BouncyCastleProvider支持
        Security.addProvider(new BouncyCastleProvider());

        // 初始化KeyGenerator
        KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA224");

        // 产生秘密密钥
        SecretKey secretKey = keyGenerator.generateKey();

        // 获得密钥
        return secretKey.getEncoded();
    }

    /**
     * HmacSHA224消息摘要
     * 
     * @param data
     *            待做消息摘要处理的数据
     * @param byte[] 密钥
     * @return byte[] 消息摘要
     * @throws Exception
     */
    public static byte[] encodeHmacSHA224(byte[] data, byte[] key)
            throws Exception
    {

        // 加入BouncyCastleProvider支持
        Security.addProvider(new BouncyCastleProvider());

        // 还原密钥
        SecretKey secretKey = new SecretKeySpec(key, "HmacSHA224");

        // 实例化Mac
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());

        // 初始化Mac
        mac.init(secretKey);

        // 执行消息摘要
        return mac.doFinal(data);
    }

    /**
     * HmacSHA224Hex消息摘要
     * 
     * @param data
     *            待做消息摘要处理的数据
     * @param byte[] 密钥
     * @return String 消息摘要
     * @throws Exception
     */
    public static String encodeHmacSHA224Hex(byte[] data, byte[] key)
            throws Exception
    {

        // 执行消息摘要
        byte[] b = encodeHmacSHA224(data, key);

        // 做十六进制转换
        return new String(Hex.encode(b));
    }
}

五 使用密钥协商协议

密钥协商协议使得多个通信方能够通过网络安全地交换密钥,从而进行加密通信。

【Java安全技术探索之路系列:Java可扩展安全架构】之七:JCE(三):JCE编程模型

标签:jce-编程模型   加密   解密   架构   

原文地址:http://blog.csdn.net/allenwells/article/details/46505871

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!