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

JAVA-RSA/DES加密实现备忘.

    博客分类:
  • JAVA
 
阅读更多

1. RSAEncryptor.java

public class RSAEncryptor {

    private PublicKey rsaPublicKey;

    private Cipher cipher;

    // 1024位RSA加密算法中,当加密明文长度超过117个字节后,会出现异常,所以采用分段加密
    private final static int PT_LEN = 117;
    private final static String SPLIT_CHAR="|";//分段加密/解密,段落分割符,

    private RSAEncryptor(String publicKey) throws Exception{
        cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        this.rsaPublicKey = this.generatePublic(publicKey);
    }

    private  PublicKey generatePublic(String key) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(key);//UTF-8

        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    /**
     * 加密输入的明文字符串
     * 当value的字节长度大于117,将会采用分段加密,即依次对117个字节,加密,并通过"|"对段落进行分割,
     * 请解密者注意
     * @param value 加密后的字符串 1024个字节长度
     * @return
     */
    public String encrypt(String value) throws IOException {
        if(value == null || value.isEmpty()){
            return value;
        }
        return encryptBySeg(value.getBytes());
    }

    /**
     * 分段加密
     * @param plainText,各个段落以'|'分割
     * @return
     * @throws IOException
     */
    private String encryptBySeg(byte[] plainText) throws IOException{
        //获取加密段落个数
        int length = plainText.length;//
        int mod = length %PT_LEN;//余数
        int ptime = length /PT_LEN;//段数
        int ptimes = (mod == 0 ? ptime : ptime +1);
        StringBuffer sb = new StringBuffer();
        int i = 0;
        while(i < ptimes){
            int from = i * PT_LEN;
            int to = Math.min(length, (i+1)*PT_LEN);
            byte[] temp = Arrays.copyOfRange(plainText, from, to);
            sb.append(Base64.encodeBase64String(encrypt(temp)));//apache commons-codec
            if(i != (ptimes - 1)){
                sb.append(SPLIT_CHAR);
            }
            i++;
        }
        return sb.toString();

    }
    /**
     * 加密
     * @param plainTextArray
     * @return
     */
    private byte[] encrypt(byte[] plainTextArray) {
        try {
            cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey);
            return cipher.doFinal(plainTextArray);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 根据公钥,获取加密工具类实例
     * @param publicKey
     * @return
     */
    public static RSAEncryptor getInstance(String publicKey) throws Exception{
        if(publicKey == null || publicKey.isEmpty()){
            return null;
        }
        return new RSAEncryptor(publicKey);
    }

    /**
     * 重置加密key
     * @param publicKey
     */
    public synchronized void reset(String publicKey) throws Exception{
        this.rsaPublicKey = this.generatePublic(publicKey);
    }
}

2.RSADecryptor.java

public class RSADecryptor {

    private PrivateKey rsaPrivateKey;
    private Cipher cipher;
    private final static String SPLIT_CHAR="|";//分段加密/解密,段落分割符
    private RSADecryptor(String privateKey) throws Exception{
        cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        this.rsaPrivateKey = this.generatePrivate(privateKey);
    }
    /**
     * 获取私钥,根据已经生成的合格的RSA私钥字符串,转化成RSAPrivateKey对象,(PKCS8EncodedKeySpec)
     * @param key
     * @return
     * @throws Exception
     */
    private PrivateKey generatePrivate(String key) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(key);

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }

    /**
     * 解密
     *
     * @param encrypt 加密后的二进制字节
     *
     * @return 解密后的二进制
     */
    private  byte[] decrypt(byte[] encrypt) {
        try {
            cipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey);
            byte[] decryptByteArray = cipher.doFinal(encrypt);
            return decryptByteArray;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 对加密数据进行解密,自动分段
     *
     */
    public String decrypt(String plainTextA) {
        StringTokenizer tokenizer = new StringTokenizer(plainTextA,SPLIT_CHAR);
        StringBuffer sb = new StringBuffer();
        while (tokenizer.hasMoreTokens()) {
            byte[] tmp;
            String tmpBase64Str = (String) tokenizer.nextElement();
            try {
                tmp = Base64.decodeBase64(getFormatBase64String(tmpBase64Str, 1));
                tmp = decrypt(tmp);
                sb.append(new String(tmp));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //替换空格
        return sb.toString().replace("\u0000","");

    }

    /**
     *
     * @param str
     * @return
     */
    private String getFormatBase64String(String str,int times){
        int timesModes = (int) (Math.pow(1.5, times-1)*10);
        //这个数字是由RSA1024位 及base 64增大0.5倍,具体计算公式为:rsa密钥长度/8*(1.5);
        final int  subLength = 172 * timesModes/10;
        return str.substring(str.length()-subLength, str.length());

    }

    /**
     * 根据私钥获取解密对象
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static RSADecryptor getInstance(String privateKey) throws Exception{
        if(privateKey == null || privateKey.isEmpty()) {
            return null;
        }
        return new RSADecryptor(privateKey);
    }

    /**
     * 重置解密key
     */
    public void reset(String privateKey) throws Exception{
        this.rsaPrivateKey = this.generatePrivate(privateKey);
    }
}

3.RSABuilder.java

public class RSABuilder {

	public static final int KEY_SIZE = 1024;
	
	/**
	 * 生成密钥对,注意需要对public key进行位运算.
	 * @return
	 */
	public static KeyPair generateKeyPair(){
		try {
			KeyPairGenerator keyPairGen = (KeyPairGenerator) KeyPairGenerator.getInstance("RSA");
			keyPairGen.initialize(KEY_SIZE, new SecureRandom());
			KeyPair keyPair = keyPairGen.genKeyPair();
			return keyPair;
		} catch (NoSuchAlgorithmException e) {
			return null;
		}
	}
	
	public static void main(String[] args) throws Exception{
		KeyPair keyPair = RSABuilder.generateKeyPair();
		PrivateKey privateKey = keyPair.getPrivate();
		String privateKeyStr = Base64.encodeBase64String(privateKey.getEncoded());
		System.out.println("----Private Key--");
		System.out.println(privateKeyStr);
		PublicKey publicKey = keyPair.getPublic();
		String publicKeyStr = Base64.encodeBase64String(publicKey.getEncoded());
		System.out.println("----Public Key--");
		System.out.println(publicKeyStr);
		String tmp = "123456789";
		RsaEncoder rsaEncoder = RsaEncoder.getInstance(publicKeyStr);
		String result = rsaEncoder.encrypt(tmp);
		RsaDecoder rsaDecoder = RsaDecoder.getInstance(privateKeyStr);
		System.out.println(rsaDecoder.dencrypt(result));
		
	}
}

4.DESUtils.java

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

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.SecureRandom;
import java.util.Arrays;


public class DESUtils {
    private static final String DES = "DES";
    private static final String PADDING = "DES/ECB/PKCS5Padding";
    private static final String DEFAULT_ENCODING = "utf-8";
    private static final int KEY_LENGTH = 8;

    /**
     * 加密
     * @param key 密钥
     * @param target 需要加密的数据
     * @return
     */
    public final static String encrypt(String target, String key) {
        try {
            return Base64.encodeBase64String(encrypt(target.getBytes(DEFAULT_ENCODING), key
                    .getBytes(DEFAULT_ENCODING)));
        } catch (Exception e) {
            //
        }
        return null;

    }

    public static byte[] encrypt(byte[] src, byte[] key) throws Exception {
        if(key.length < KEY_LENGTH) {
            throw new IllegalArgumentException("key length must be 8");
        }
        byte[] sha1Key = DigestUtils.sha1(key);
        key = Arrays.copyOf(sha1Key,KEY_LENGTH);//only use first 8 bytes
        SecureRandom sr = new SecureRandom();
        DESKeySpec dks = new DESKeySpec(key);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
        SecretKey secretkey = keyFactory.generateSecret(dks);
        Cipher cipher = Cipher.getInstance(PADDING);
        cipher.init(Cipher.ENCRYPT_MODE, secretkey, sr);
        return cipher.doFinal(src);

    }
    public final static String decrypt(String target, String key) {
        try {
            //base64,default-charset is UTF-8
            return new String(decrypt(Base64.decodeBase64(target),
                    key.getBytes(DEFAULT_ENCODING)), DEFAULT_ENCODING);

        } catch (Exception e) {
            //
        }
        return null;
    }

    public static byte[] decrypt(byte[] src, byte[] key) throws Exception {
        if(key.length < KEY_LENGTH) {
            throw new IllegalArgumentException("key length must be 8");
        }
        byte[] sha1Key = DigestUtils.sha1(key);
        key = Arrays.copyOf(sha1Key,KEY_LENGTH);
        SecureRandom sr = new SecureRandom();
        DESKeySpec dks = new DESKeySpec(key);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
        SecretKey secretkey = keyFactory.generateSecret(dks);
        Cipher cipher = Cipher.getInstance(PADDING);
        cipher.init(Cipher.DECRYPT_MODE, secretkey, sr);
        return cipher.doFinal(src);
    }


    public static void main(String[] args) {
        String key = "01234567890012412312241";
        String raw = "xyszewwre";
        String result = encrypt(raw,key);
        System.out.println(result);
        System.out.println(decrypt(result,key));
    }

}

 

5.AESUtils.java

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

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Arrays;


/**
 * 密钥最小长度为128
 */
public class AESUtils {
    private static final String AES = "AES";
    private static final String PADDING = "AES/ECB/PKCS5Padding";
    private static final String DEFAULT_ENCODING = "utf-8";
    private static final int KEY_LENGTH = 16;

    /**
     * 加密
     * @param key 密钥
     * @param target 需要加密的数据
     * @return
     */
    public final static String encrypt(String target, String key) {
        try {
            return Base64.encodeBase64String(encrypt(target.getBytes(DEFAULT_ENCODING), key
                    .getBytes(DEFAULT_ENCODING)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    public static byte[] encrypt(byte[] src, byte[] key) throws Exception {
        if(key.length < KEY_LENGTH) {
            throw new IllegalArgumentException("key length must be 16");
        }
        byte[] sha1Key = DigestUtils.sha1(key);
        key = Arrays.copyOf(sha1Key, KEY_LENGTH);//only use first 16 bytes
        SecureRandom sr = new SecureRandom();
        SecretKeySpec dks = new SecretKeySpec(key,AES);
        Cipher cipher = Cipher.getInstance(PADDING);
        cipher.init(Cipher.ENCRYPT_MODE, dks, sr);
        return cipher.doFinal(src);

    }
    public final static String decrypt(String target, String key) {
        try {
            //base64,default-charset is UTF-8
            return new String(decrypt(Base64.decodeBase64(target),
                    key.getBytes(DEFAULT_ENCODING)), DEFAULT_ENCODING);

        } catch (Exception e) {
            //
        }
        return null;
    }

    public static byte[] decrypt(byte[] src, byte[] key) throws Exception {
        if(key.length < KEY_LENGTH) {
            throw new IllegalArgumentException("key length must be 16");
        }
        byte[] sha1Key = DigestUtils.sha1(key);
        key = Arrays.copyOf(sha1Key, KEY_LENGTH);
        SecureRandom sr = new SecureRandom();
        SecretKeySpec dks = new SecretKeySpec(key,AES);
        Cipher cipher = Cipher.getInstance(PADDING);
        cipher.init(Cipher.DECRYPT_MODE, dks, sr);
        return cipher.doFinal(src);
    }


    public static void main(String[] args) {
        String key = "12345678901234567890";
        String raw = "xyzeaessf";
        String result = encrypt(raw,key);
        System.out.println(result);
        System.out.println(decrypt(result,key));
    }

}

 

 

1
0
分享到:
评论
1 楼 darkjune 2013-08-14  
思路不错, 看过挺好

相关推荐

Global site tag (gtag.js) - Google Analytics