java各种加密方法实现

一般来讲,在java上实现加密解密算法,有3种方式。

  1. 自行实现算法、
  2. 使用java自带的crypto软件包
  3. 使用第三方库

本文讲述一下第二种使用方法。我最开始也是找了很多这方面的资料,但是总感觉还是缺乏一些细节。现将我的一些心得与大家分享。

本文给出的例子基于下面的blog中所给出的例子。

blog.csdn.net/wildandfly/article/details/21521857

首先,现代密码学算法大致可以分为3个大块。分别是对称加密symmetric,非对称加密asymmetric,消息摘要hash。

本文实现了下列的几种算法,其中每个package中的算法都非常类似。
这里写图片描述

不罗嗦,直接上代码

http://download.csdn.net/detail/watch_ch/9465641

1对称加密

以AES为例。注意其中keygenerator函数,其中keygenerator.getInstance()函数需要输入对应的密码方法,从而生成对应长度的key。

这里,我查了下doc。可以传入的参数如下图。

这里写图片描述

package com.zhicheng.cryptogram;

import java.security.NoSuchAlgorithmException;

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

import org.apache.commons.codec.binary.Base64;

import com.alibaba.fastjson.JSONObject;

/**
 * 根据指定的16位aes_key,对id进行加解密
 * @author wb-zcf274530
 *
 */
public class SymmetricEncryption {

    //密钥生成支持16位字符
    private static final String aes_key = "assistant7654321";

    public static String encrypt(long id) {
         byte[] key = Base64.decodeBase64(aes_key);
         byte[] input = String.valueOf(id).getBytes();
         byte[] encryptBytes = Cryptos.aesEncrypt(input, key);
         return Base64.encodeBase64URLSafeString(encryptBytes);
    }

    public static Long decrypt(String securityId) {
        byte[] key = Base64.decodeBase64(aes_key);
        String value = Cryptos.aesDecrypt(Base64.decodeBase64(securityId), key);
        return Long.parseLong(value);
    }

    static class Cryptos{

        private static final String AES                      = "AES";

        public static byte[] aesEncrypt(byte[] input,byte[] key) {
            // ENCRYPT_MODE表示加密模式 
            return aes(input,key,Cipher.ENCRYPT_MODE);
        }

        public static String aesDecrypt(byte[] input,byte[] key) {
            // DECRYPT_MODE表示解密模式 
            byte[] decypt = aes(input,key,Cipher.DECRYPT_MODE);
            return new String(decypt);
        }

        private static byte[] aes(byte[] input,byte[] key,int mode) {
            try {   
                //根据指定关键字进行获取加密密钥
                SecretKey secretKey = new SecretKeySpec(key, AES);
                //实例化支持AES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
                Cipher cipher = Cipher.getInstance(AES);
                //根据密钥,对Cipher对象进行初始化
                cipher.init(mode, secretKey);
                return cipher.doFinal(input);
            }catch(Exception e) {
                throw unchecked(e);
            }
        }

        /**
         * 生成密钥
         * @return
         */
        public static String generateKey() {
            KeyGenerator keygen = null;
            try {
                keygen = KeyGenerator.getInstance("AES");
            } catch (NoSuchAlgorithmException e) {
            }       
            //SecretKey 负责保存对称密钥    
            SecretKey deskey = keygen.generateKey();
            return Base64.encodeBase64String(deskey.getEncoded());
        }
        /**
         * 将CheckedException转换为UncheckedException.
         */
        private static RuntimeException unchecked(Exception e) {
            if (e instanceof RuntimeException) {
                return (RuntimeException) e;
            } else {
                return new RuntimeException(e);
            }
        }



        public static void main(String[] args) throws NoSuchAlgorithmException {
            /*String result = encrypt(1989L);
            System.out.println(result);;
            System.out.println("the encrypt:"+decrypt(result));*/

            KeyGenerator keygen = KeyGenerator.getInstance("AES");       
            //SecretKey 负责保存对称密钥    
            SecretKey deskey = keygen.generateKey();
            System.out.println(Base64.encodeBase64String(deskey.getEncoded()));
        }

    }
}

2非对称加密

以rsa为例,由于公钥加密体系需要2个key值,故产生key值的函数也发生了改变。

keypairgenerator.getInstance()函数同样需要传入加密的方法,产生对应的key值。

这里,我也查了下doc,如下。
这里写图片描述

package com.zhicheng.cryptogram;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.apache.commons.codec.binary.Base64;

/**
 * 非对称性加密(公私钥加密)
 * 1、每次生成的公私钥对都是不同的,所以要求对其进行存储
 * @author wb-zcf274530
 *
 */
public class AsymmetricEncryption {

    private static final String RSA = "RSA";

     /** 
     * 加密 
     *  
     * @param publicKey 
     * @param srcBytes 
     * @return 
     * @throws NoSuchAlgorithmException 
     * @throws NoSuchPaddingException 
     * @throws InvalidKeyException 
     * @throws IllegalBlockSizeException 
     * @throws BadPaddingException 
     */  
    public byte[] encrypt(String publicKey, byte[] srcBytes) throws NoSuchAlgorithmException,  
            NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {  
        try {
            if (publicKey != null) {  
                PublicKey key = getPublicKey(publicKey);
                 return rsa(key,srcBytes,Cipher.ENCRYPT_MODE);  
            }  
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;  
    }

    /**
     * 获取公钥
     * @param filename
     * @return
     * @throws Exception
     */
    private static PublicKey getPublicKey(String publicKey) throws Exception { 
        byte[] publicKeys = Base64.decodeBase64(publicKey);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeys); 
        KeyFactory kf = KeyFactory.getInstance(RSA);  
        return kf.generatePublic(spec); 
    } 

    /**
      * 获取私钥
      * @param filename
      * @return
      * @throws Exception
      */
     private static PrivateKey getPrivateKey(String privateKey)throws Exception { 
         byte[] keyBytes = Base64.decodeBase64(privateKey);
         PKCS8EncodedKeySpec spec =new PKCS8EncodedKeySpec(keyBytes); 
         KeyFactory kf = KeyFactory.getInstance(RSA); 
         return kf.generatePrivate(spec); 
       } 



    /** 
     * 解密 
     *  
     * @param privateKey 
     * @param srcBytes 
     * @return 
     * @throws NoSuchAlgorithmException 
     * @throws NoSuchPaddingException 
     * @throws InvalidKeyException 
     * @throws IllegalBlockSizeException 
     * @throws BadPaddingException 
     */  
    public byte[] decrypt(String privateKey, byte[] srcBytes) throws NoSuchAlgorithmException,  
            NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {  
        try {
            if (privateKey != null) {  
                PrivateKey key = getPrivateKey(privateKey);
                // 根据公钥,对Cipher对象进行初始化  
               return rsa(key,srcBytes,Cipher.DECRYPT_MODE); 
            } 
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;  
    }  

    public byte[] rsa(Key key,byte[] input,int mode) throws IllegalBlockSizeException, 
        BadPaddingException, InvalidKeyException, 
        NoSuchAlgorithmException, NoSuchPaddingException {
        Cipher cipher = Cipher.getInstance(RSA); 
        // 根据公钥,对Cipher对象进行初始化  
        cipher.init(mode, key);  
        byte[] resultBytes = cipher.doFinal(input);  
        return resultBytes;  
    }
    /** 
     * @param args 
     * @throws NoSuchAlgorithmException 
     * @throws BadPaddingException 
     * @throws IllegalBlockSizeException 
     * @throws NoSuchPaddingException 
     * @throws InvalidKeyException 
     */  
    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException,  
            IllegalBlockSizeException, BadPaddingException {  
        AsymmetricEncryption rsa = new AsymmetricEncryption();  
        String msg = "www.suning.com/index.jsp";  
        // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象  
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(RSA);  
        // 初始化密钥对生成器,密钥大小为1024位  
        keyPairGen.initialize(1024);  
        // 生成一个密钥对,保存在keyPair中  
        KeyPair keyPair = keyPairGen.generateKeyPair();  
        // 得到私钥  
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();  
        // 得到公钥  
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  

        // 用公钥加密  
        byte[] srcBytes = msg.getBytes();  
        byte[] resultBytes = rsa.encrypt(Base64.encodeBase64String(publicKey.getEncoded()), srcBytes);  
        System.out.println(Base64.encodeBase64String(publicKey.getEncoded()));
        // 用私钥解密  
        byte[] decBytes = rsa.decrypt(Base64.encodeBase64String(privateKey.getEncoded()), resultBytes);  
        System.out.println(Base64.encodeBase64String(privateKey.getEncoded()));
        System.out.println("明文是:" + msg);  
        System.out.println("加密后是:" + new String(resultBytes));  
        System.out.println("解密后是:" + new String(decBytes));  
    }  
}

3hash函数
这个由于我没有用到,暂时就不写了,以后再补上。


注意:

在1、2中除了keygenerator需要传递密码的方法,cipher在初始化时也需要指定其参数。如下所示。
这里写图片描述

原文参见:http://blog.csdn.net/watch_ch/article/details/50923563

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值