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

本文介绍了一种使用RSA和DES算法进行数据加密和解密的方法。通过分段处理解决大块数据加密的问题,并提供了生成密钥对的示例。同时展示了如何利用Java进行具体的加解密操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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";
	
	public final static String encrypt(String code, String key) {
		try {
			return Base64.encodeBase64String(encrypt(code.getBytes(DEFAULT_ENCODING), key
					.getBytes(DEFAULT_ENCODING)));
		} catch (Exception e) {
			//
		}
		return null;

	}
	
	public static byte[] encrypt(byte[] src, byte[] key) throws Exception {
		SecureRandom sr = new SecureRandom();
		DESKeySpec dks = new DESKeySpec(key);
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
		SecretKey securekey = keyFactory.generateSecret(dks);
		Cipher cipher = Cipher.getInstance(PADDING);
		cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
		return cipher.doFinal(src);

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

		} catch (Exception e) {
			//
		}
		return null;
	}
	
	public static byte[] decrypt(byte[] src, byte[] key) throws Exception {
		SecureRandom sr = new SecureRandom();
		DESKeySpec dks = new DESKeySpec(key);
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
		SecretKey securekey = keyFactory.generateSecret(dks);
		Cipher cipher = Cipher.getInstance(PADDING);
		cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
		return cipher.doFinal(src);
	}

	
	public static void main(String[] args) {
		String tmp = DESUtils.encrypt("821", "yc2JffcREheFQlYFIAY5f9sY7uflgBTo");
        System.out.print(DesEncoder.decrypt(tmp, "yc2JffcREheFQlYFIAY5f9sY7uflgBTo"));
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值