`
blue2048
  • 浏览: 178237 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

RSA分段加密解密

阅读更多
package com.sankuai.meituan.waimai.common;

import org.apache.commons.lang.ArrayUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import sun.security.rsa.RSAPrivateKeyImpl;
import sun.security.rsa.RSAPublicKeyImpl;
import sun.security.util.DerValue;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;

/**
 *  Date: 14-9-18
 * Time: 下午4:20
 */
public class RSAHelper {

    
    public static final int ENCODE_MAX = 117;
    public static final int DECODE_MAX = 128;
    

    public static String decode(String encBase64String,String privateKeyString) throws Exception {
        BASE64Decoder base64Decoder = new BASE64Decoder();
        byte[] desEncodeRead = base64Decoder.decodeBuffer(privateKeyString);//
        DerValue d = new DerValue(desEncodeRead);
        RSAPrivateKey privateKey= (RSAPrivateKey) RSAPrivateKeyImpl.parseKey(d);
        Cipher cipher =Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] src = base64Decoder.decodeBuffer(encBase64String);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        for(int i=0; i<src.length; i+= DECODE_MAX){
            byte[] toDecodeSegment = ArrayUtils.subarray(src, i,i+DECODE_MAX);
            byte[] destByte = cipher.doFinal(toDecodeSegment);
            System.out.println("decode"+destByte.length);
            out.write(destByte);
        }
        byte[] decode = out.toByteArray();
        return new String(decode, "UTF-8");
    }
    

    public static String encode(String src, String publicKey) throws Exception {
        BASE64Decoder base64Decoder = new BASE64Decoder();
        BASE64Encoder base64Encoder = new BASE64Encoder();
        byte[] desEncodeRead = base64Decoder.decodeBuffer(publicKey);//
        DerValue d = new DerValue(desEncodeRead);
        RSAPublicKey p = (RSAPublicKey) RSAPublicKeyImpl.parse(d);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, p);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] toEncode = src.getBytes();
        for(int i=0; i<toEncode.length; i+= ENCODE_MAX){
            byte[] toEncodeSegment = ArrayUtils.subarray(toEncode, i,i+ENCODE_MAX);
            byte[] ecodeSegemnt = cipher.doFinal(toEncodeSegment);
            System.out.println("adfdsSS"+ecodeSegemnt.length);
            out.write(ecodeSegemnt);
        }
        byte[] encode = out.toByteArray();
        return base64Encoder.encode(encode);
    }

    /**
     * return map siz KEY为public key value为private key   BASE64串
     */
    public static Map generateRSAKey() throws NoSuchAlgorithmException {
        BASE64Encoder base64Encoder = new BASE64Encoder();
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        keyPairGen.initialize(1024);
        KeyPair keyPair = keyPairGen.generateKeyPair();
        // Generate keys
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        byte[] privateEncode = privateKey.getEncoded();
        byte[] publicEncode = publicKey.getEncoded();
        String privateKeyBase64 = base64Encoder.encode(privateEncode);
        String publicKeyBase64 = base64Encoder.encode(publicEncode);
        Map retValue = new HashMap(1);
        retValue.put(publicKeyBase64, privateKeyBase64);
        return retValue;
    }
    


}

 

RSA/ECB/PKCS1Padding 算法,加密字节最大117,但不论设置到大,加密后的字节数组大小为128,
解密必须按128个字节一组进行,否则报错,128个字节一组实际上也保证了分段加加密是可逆的,分段
解密后能得到加密前的字节数组

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics