`
QING____
  • 浏览: 2250785 次
  • 性别: 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  
思路不错, 看过挺好

相关推荐

    基于java的开发源码-用Java加密类实现DES、RSA及SHA的加密算法.zip

    基于java的开发源码-用Java加密类实现DES、RSA及SHA的加密算法.zip 基于java的开发源码-用Java加密类实现DES、RSA及SHA的加密算法.zip 基于java的开发源码-用Java加密类实现DES、RSA及SHA的加密算法.zip 基于java的...

    C#-RSA非对称加密公钥加密.rar

    6. **C# ConsoleApplication1**:这个文件名暗示压缩包内可能包含一个控制台应用程序,该程序可能演示了如何在C#中实现RSA公钥加密的完整流程,包括密钥生成、数据加密、密文存储以及解密恢复原始数据。 在实际应用...

    Java-RSA-DES.rar_des javascript_doc_rsa_rsa des文件加密

    这种混合加密模式称为RSA-DES或RSA与DES的结合使用。 在提供的文档"Java实现文件的RSA和DES加密算法.doc"中,可能包含了如何在Java编程环境下实现这两种加密算法的详细步骤、代码示例以及可能遇到的问题和解决方法...

    Java实现文件的RSA和DES加密

    Java 实现文件的 RSA 和 DES 加密 在现代密码技术中,根据密钥类型的不同,可以将其分为两类:对称加密算法(秘密钥匙加密)和非对称加密算法(公开密钥加密)。对称加密算法用来对敏感数据等信息进行加密,常用的...

    微信小程序-微信小程序-RSA-签名-验签-加密-解密

    var RSA = require('../../utils/wxapp_rsa.js') 2、调用 var privateKey_pkcs1 = '-----BEGIN RSA PRIVATE KEY-----MIICXQIBAAKBgQCk7WKdggwBOtteLL5sPom8RYCjuw0hy6R1jH39tCaep1Dns02bi4CYHk2dSR / t0ABgF5...

    基于Java的实例源码-用Java加密类实现DES、RSA及SHA的加密算法.zip

    基于Java的实例源码-用Java加密类实现DES、RSA及SHA的加密算法.zip

    js-rsa-jsencrypt.min.js.zip

    `js-rsa-jsencrypt.min.js.zip`这个压缩包提供了一个JavaScript实现的RSA加密库,名为`js-rsa-jsencrypt.min.js`,它允许开发者在前端对数据进行加密,确保数据在传输过程中的安全。 非对称加密的核心在于一对密钥...

    AES-RSA-DES加密算法详解

    网络安全中的对称加密AES、DES和非对称加密算法RSA详解

    bcprov-jdk16-146-RSA.jar RAS加解密公私钥

    RSA算法是一种非对称加密算法,它在信息安全领域扮演着重要的角色,特别是在数据加密、数字签名和密钥交换等方面。公私钥加解密是RSA的核心特性,它使用一对密钥,即公钥和私钥,来进行加密和解密操作。这种机制确保...

    RSA加密解密 PHP JS

    var privateKey = '-----BEGIN RSA PRIVATE KEY-----...'; // 私钥字符串 // 使用公钥加密 var data = '这是要加密的数据'; var encrypted = CryptoJS.RSAPublicEncrypt(publicKey, CryptoJS.enc.Utf8.parse(data))...

    JAVA - RSA- JS 加密

    此主题涉及到的知识点包括RSA的原理、JAVA和JavaScript实现RSA加密的过程,以及如何在两者之间进行互操作。 1. **RSA算法原理**: RSA(Rivest-Shamir-Adleman)算法基于大数因子分解的困难性,生成一对公钥和私钥...

    JAVA实现RSA、DES加密

    JAVA 实现 RSA、DES 加密是密码学中的一种重要实现,通过 JAVA 语言实现 RSA 非对称加密算法和 DES 对称加密算法。以下是对 JAVA 实现 RSA、DES 加密的详细知识点: 一、基础知识 现代密码技术可以分为两类:对称...

    java-RSA.rar_Java实现RSA_java RSA_rsa java_rsa javascript_rsa加密算法

    在Java中实现RSA加密算法,可以确保数据的安全传输,防止数据在传输过程中被窃取或篡改。 RSA的核心原理基于大数因子分解的困难性。公钥是由两个大素数p和q的乘积n以及欧拉函数φ(n)(φ(n) = (p-1)(q-1))的因数e...

    数据加密/签名(RSA/DES/MD5/CRC32/SHA1)

    本资源包含一套成型的dll库,只需拷贝里面的include/lib/...里面涵盖常用的数据加密算法(RSA/DES),数据签名(MD5/CRC32/SHA1),源代码暂不开放(主要对网上的代码,做得二次封装,爬坑及优化,哈哈哈哈……)

    bcprov-jdk16-1.46.jar

    Bouncy Castle是Java平台上的一个开源加密库,提供了对多种加密标准的支持,如RSA、AES、DES等,以及SSL/TLS协议和PKCS#7、PKCS#12、X.509证书等。 描述中提到的"bcprov-jdk16-1.46.jar"表明这是针对Java 1.6版本的...

    加密系统 DES RSA

    加密系统 DES RSA 加密系统 DES RSA 加密系统 DES RSA

    C#和Java实现互通的RSA&DES加解密算法

    本话题主要关注如何在C#和Java之间通过RSA和DES加密算法实现数据的安全互通。RSA是一种非对称加密算法,适用于小量数据加密,如密钥交换;而DES是对称加密算法,适合大量数据的快速加密,但安全性相对较低。 首先,...

    rsa-des.rar_DES rsa_java res des加密通信_rsa_rsa通信_加密通信

    在这个"rsa-des.rar_DES rsa_java res des加密通信_rsa_rsa通信_加密通信"的资源中,我们主要探讨的是两种常见的对称与非对称加密算法——DES(Data Encryption Standard)和RSA(Rivest-Shamir-Adleman),以及它们...

    C#加JS的RSA加密程序

    C#加JS的RSA加密程序 // RSA, a suite of routines for performing RSA public-key computations in // JavaScript. // // Requires BigInt.js and Barrett.js. // // Copyright 1998-2005 David Shapiro. // // You...

    rsa与aes混合加密java实现

    在Java项目中,`aes-rsa-java-master`可能是一个包含示例代码的项目,展示了如何在Java中实现上述过程。开发者可以通过阅读和学习这些代码,更好地理解和应用RSA与AES的混合加密。 总结,RSA和AES混合加密结合了非...

Global site tag (gtag.js) - Google Analytics