RSA加密

  引文: http://blog.csdn.net/houzuoxin/article/details/38957969

package com.lvmama.clutter.utils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import com.alibaba.dubbo.common.utils.StringUtils;

/**
 *
 * @author heyuxing
 *
 */
public class RSAFileUtil {
    public static final String CHARSET = "utf-8";
    public static final String KEY_ALGORITHM = "RSA";
    public static final String SIGN_ALGORITHM = "SHA1withRSA";
    public static String privateKeyPath = "C:\\Users\\Administrator\\Desktop\\HeartyPri.key";
    public static PrivateKey privateK;
//    private static String RSA_KEY_FILEPATH = ClutterConstant.getProperty("rsa.privatekey.filepath");
    private static Logger logger =  Logger.getLogger(RSAFileUtil.class);
    
    public static void main(String[] args) throws Exception {
        Map<String, String> dataStr = new HashMap<String, String>();
        dataStr.put("orderId", "11111");
        dataStr.put("objectType", "objectType");
        dataStr.put("payAmountFen", "4154");
        dataStr.put("paymentType", "paymentType");
        dataStr.put("bizType", "bizType");
        dataStr.put("royaltyParameters", "royaltyParameters");
        dataStr.put("getPromotAmountFen", "1245");
        System.out.println("map 集合: " + dataStr.toString());        
        String ss = signMapNotEncode(dataStr);
        System.out.println("加签值: " + ss);
    }

    protected static String signMapNotEncode(Map<String, String> params) throws Exception {
        String text = createLinkString(params, false);
        return sign(text, CHARSET);
    }
 
    protected static String sign(String text, String charset) throws Exception {
        PrivateKey privateK = getPrivateKey();
        Signature signature = Signature.getInstance(SIGN_ALGORITHM);
        signature.initSign(privateK);
        signature.update(getContentBytes(text, charset));
        byte[] result = signature.sign();
        return Base64.encodeBase64String(result);
    }

    private static PrivateKey getPrivateKey() {
        if(privateK == null) {
            synchronized (RSAFileUtil.class) {
                if(privateK == null) {
                    FileInputStream fis = null;
                    ObjectInputStream ois = null;
                    try {
                        if(StringUtils.isBlank(privateKeyPath)) {
//                            privateKeyPath = "/var/www/webapps/client-clutter/WEB-INF/classes/HeartyPri.key";
                            privateKeyPath = "C:\\Users\\Administrator\\Desktop\\HeartyPri.key";
                        }
                        fis = new FileInputStream(privateKeyPath);
                        ois = new ObjectInputStream(fis);
                        privateK = (PrivateKey) ois.readObject();
                    } catch (Exception e) {
                        logger.error("....RSAFileUtil.getPrivateKey is error....",e);
                        e.printStackTrace();
                    } finally {
                        if (ois != null ) {
                            try {
                                ois.close();
                            } catch (IOException e) {
                                logger.error("....RSAFileUtil.getPrivateKey is error....",e);
                                e.printStackTrace();
                            }
                        }
                        if (fis != null ) {
                            try {
                                fis.close();
                            } catch (IOException e) {
                                logger.error("....RSAFileUtil.getPrivateKey is error....",e);
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }

        return privateK;
    }

    private static byte[] getContentBytes(String content, String charset) {
        if (charset == null || "".equals(charset)) {
            return content.getBytes();
        }
        try {
            return content.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:"
                    + charset);
        }
    }

    public static String createLinkString(Map<String, String> params,
            boolean encode) {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        String prestr = "";
        Charset charset = Charset.forName("UTF-8");
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            if (StringUtils.isEmpty(value)) {
                continue;
            }
            if (encode) {
                try {
                    value = URLEncoder.encode(value, charset.name());
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }

            if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }

        return prestr;
    }
}

通过生成工具,生成一对公钥,私钥;

RSAKeyGeneratorL:


package com.lvtu.utils;


import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * 用于生产RSA公钥、私钥
 * @author wxliyong
 * @date 2016-10-14 15:32:41
 */
public class RSAKeyGenerator {
    /** 这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低 */
    private static final int KEY_SIZE = 512;
    
    public static void main(String[] args) throws Exception {
        KeyPair keyPair = generateKeyPair();
        PublicKey pubKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        System.out.println("公钥:" + Base64.encodeBase64String(pubKey.getEncoded()));
        System.out.println("私钥:" + Base64.encodeBase64String(privateKey.getEncoded()));
    }
    
    /**
     * 生成密钥对
     *
     * @return KeyPair
     * @throws Exception
     */
    private static KeyPair generateKeyPair() throws Exception {
        try {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", new BouncyCastleProvider());
            keyPairGen.initialize(KEY_SIZE, new SecureRandom());
            KeyPair keyPair = keyPairGen.genKeyPair();
            return keyPair;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }
}


utill:

package com.lvtu.utils;

import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

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

/**
 * RSA加密解密工具类<br>
 * <font color="red">1、使用公钥加密,必须使用私钥解密;</font><br>
 * <font color="red">2、使用私钥加密,则必须使用公钥解密</font><br>
 * @author wxliyong
 * @date 2016-10-14 15:33:25
 */
public class RSAUtils {
    
    private static final String DEFAULT_CHARACTER = "UTF-8";
    /** RSA最大加密明文大小 */  
    private static final int MAX_ENCRYPT_BLOCK = 117;  
    /** RSA最大解密密文大小  */  
    private static final int MAX_DECRYPT_BLOCK = 128;  
    public static void main(String[] args) throws Exception {
        String pubKey = "MD0wDQYJKoZIhvcNAQEBBQADLAAwKQIiATEgdQwKkkIpjzdA3dqyWOHRj6YwLZICvX4FzCYFT8W4HQIDAQAB";
        String primaryKey = "MIHGAgEAMA0GCSqGSIb3DQEBAQUABIGxMIGuAgEAAiIBMSB1DAqSQimPN0Dd2rJY4dGPpjAtkgK9fgXMJgVPxbgdAgMBAAECISaLmh2uTDGtfFkXia8x7oZ717KoPHSCWHcooEuAqOoeRQIRFsniPNjNomPbmtNHhNF36XsCEQ1jspMZf40QRdXyZw2bULVHAhEDQE48rBm6X1DHZ/k+I7xd3QIRA60DMW8mnUuCYKITuKCTH7ECEQf2xqNQbgwQvwba5k7iZFzm";
        String content = "111111";
        String encryptByPub = encryptByPub(pubKey, content);
        System.out.println("公钥加密密文:" + encryptByPub);
        String decryptByPrimary = decryptByPrimary(primaryKey, encryptByPub);
        System.out.println("私钥解密明文:" + decryptByPrimary);
        
        
        String encryptByPrimary = encryptByPrimary(primaryKey, content);
        System.out.println("私钥加密密文:" + encryptByPrimary);
        String decryptByPub = decryptByPub(pubKey, encryptByPrimary);
        System.out.println("公钥解密明文:" + decryptByPub);
    }
    
    /**
     * 使用公钥加密
     * @param key 公钥
     * @param content 明文
     * @return String 密文
     * @throws Exception
     */
    public static String encryptByPub(String key, String content) throws Exception {
        PublicKey pubKey = getPublicKey(key);
        byte[] data = encrypt(pubKey, content.getBytes(DEFAULT_CHARACTER));
        return Base64.encodeBase64String(data);
    }
    
    /**
     * 使用私钥加密
     * @param key 私钥
     * @param content 明文
     * @return String 密文
     * @throws Exception
     */
    public static String encryptByPrimary(String key, String content) throws Exception {
        PrivateKey privateKey = getPrivateKey(key);
        byte[] data = encrypt(privateKey, content.getBytes(DEFAULT_CHARACTER));
        return Base64.encodeBase64String(data);
    }
    
    /**
     * 使用公钥解密
     * @param key 公钥
     * @param content 密文
     * @return String 明文
     * @throws Exception
     */
    public static String decryptByPub(String key, String content) throws Exception {
        PublicKey pubKey = getPublicKey(key);
        byte[] data = decrypt(pubKey, Base64.decodeBase64(content));
        return new String(data, DEFAULT_CHARACTER);
    }
    
    /**
     * 使用私钥解密
     * @param key 私钥
     * @param content 密文
     * @return String 明文
     * @throws Exception
     */
    public static String decryptByPrimary(String key, String content) throws Exception {
        PrivateKey privateKey = getPrivateKey(key);
        byte[] data = decrypt(privateKey, Base64.decodeBase64(content));
        return new String(data, DEFAULT_CHARACTER);
    }
    
    /**
     * 得到公钥
     * @param key 密钥字符串(经过base64编码)
     * @throws Exception
     */
    private static PublicKey getPublicKey(String key) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    /**
     * 得到私钥
     * @param key 密钥字符串(经过base64编码)
     * @throws Exception
     */
    private static PrivateKey getPrivateKey(String key) throws Exception {
        byte[] keyBytes;
        keyBytes =  Base64.decodeBase64(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }
    
    /**
     * 加密
     * @param key 加密的密钥/公钥
     * @param data 明文数据
     * @return 密文数据
     * @throws Exception
     */
    private static byte[] encrypt(Key key, byte[] data) throws Exception {
        try {
            Cipher cipher = Cipher.getInstance("RSA");  
            cipher.init(Cipher.ENCRYPT_MODE, key);  
            int inputLen = data.length;  
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] cache;  
            // 对数据分段加密  
            for (int offSet = 0;  offSet<inputLen; offSet += MAX_ENCRYPT_BLOCK) {  
                if (inputLen - offSet > 117) {  
                    cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);  
                } else {  
                    cache = cipher.doFinal(data, offSet, inputLen - offSet);  
                }  
                out.write(cache, 0, cache.length);  
            }  
            byte[] encryptBytes = out.toByteArray();  
            out.close();
            return encryptBytes;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 解密
     * @param key 解密的密钥/公钥
     * @param raw 密文数据
     * @return 明文数据
     * @throws Exception
     */
    private static byte[] decrypt(Key key, byte[] raw) throws Exception {
        ByteArrayOutputStream out = null;
        try {
            Cipher cipher = Cipher.getInstance("RSA");  
            cipher.init(Cipher.DECRYPT_MODE, key);  
            int inputLen = raw.length;  
            out = new ByteArrayOutputStream();
            byte[] cache;  
            // 对数据分段解密
            for (int offSet = 0;  offSet<inputLen; offSet += MAX_DECRYPT_BLOCK) {  
                byte[] subData = subArray(raw, offSet, MAX_DECRYPT_BLOCK);
                cache = cipher.doFinal(subData);  
                out.write(cache, 0, cache.length);  
            }  
            byte[] decryptBytes = out.toByteArray();  
            return decryptBytes;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        } finally {
            if(out != null) {
                out.close();
            }
        }
    }
    
      /**
     *
     * 截取byte数组中指定子集
     *
     * @autor: heyuxing  2014-12-18 下午12:25:31
     * @param source 原byte数组
     * @param offset 起始索引
     * @param limit    截取的byte数组的最大长度
     * @return    
     * @return byte[]
     */
    private static byte[] subArray(byte[] source, int offset, int limit) {
        int targetLen = 0;
        if(source==null || offset>=source.length || offset<0 || limit<=0) {
            return new byte[]{};
        }else if(source.length-offset>limit) {
            targetLen = limit;
        }else {
            targetLen = source.length-offset;
        }
        byte[] target = new byte[targetLen];
        for(int i=0; i<targetLen; i++) {
            target[i] = source[offset+i];
        }
        return target;
    }
}

事例:


             String primaryKey = Constant.getInstance().getValue("param.rsa.primary.key");
                if(password.contains("%")) {
                    password = URLDecoder.decode(password, "UTF-8");
                }
                password = RSAUtils.decryptByPrimary(primaryKey, password);
                request.setPassword(password);




package com.lvmama.pet.payfront.web;

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

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.*;

/**
 * Created by Administrator on 2016/10/28.
 */
public class Tesrt {

    public static void main(String[] args) throws Exception {
        Map<String, String> dataStr = new HashMap<String, String>();
        dataStr.put("orderId", "11111");
        dataStr.put("objectType", "objectType");
        dataStr.put("payAmountFen", "4154");
        dataStr.put("paymentType", "paymentType");
        dataStr.put("bizType", "bizType");
        dataStr.put("royaltyParameters", "royaltyParameters");
        dataStr.put("getPromotAmountFen", "1245");
        System.out.println("map 集合: " + dataStr.toString());
        String sin = sign(createLinkString(dataStr, false), "C:\\Users\\Administrator\\Desktop\\rsa\\HeartyPri.key", "utf-8");
        System.out.println("加签值: " + sin);
    }

    protected static String sign(String text, String privateKeyPath, String charset) throws Exception {
        FileInputStream fis = new FileInputStream(privateKeyPath);
        ObjectInputStream ois = new ObjectInputStream(fis);
        PrivateKey privateK = (PrivateKey) ois.readObject();

        Signature signature = Signature.getInstance("SHA1withRSA");
        signature.initSign(privateK);
        signature.update(getContentBytes(text, charset));
        byte[] result = signature.sign();
        return Base64.encodeBase64String(result);
    }

    private static byte[] getContentBytes(String content, String charset) {
        if (charset == null || "".equals(charset)) {
            return content.getBytes();
        }
        try {
            return content.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
        }
    }


    public static String createLinkString(Map<String, String> params, boolean encode) {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        String prestr = "";
        Charset charset = Charset.forName("UTF-8");
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            if (StringUtils.isEmpty(value)){
                continue;
            }
            if (encode) {
                try {
                    value = URLEncoder.encode(value, charset.name());
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }

            if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }

        return prestr;
    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值