大红鹰葡京会java加密算法AES与RSA3DES加密。

 

正文介绍了3DES加密风味,加密特点,3DES凡是针对如加密,用一个密钥对情节开展加密,必须采用同一的密钥进行解密,
密钥必须安排,而且长度为24各,不足24各,用0个展开补全,本文也顺手介绍了其他加密算法,最后用java语句实现了3DES加解密

1.commons-codec使用

commons-codes
常用工具类:DigestUtils,Base64,Hex

森底加密手段大约可分成单项加密和双向加密。单项加密指经对数码进行摘要计算生成密文,密文不可逆推还原,比如来MD5、SHA等;双向加密则相反,指可拿密文逆推还原成明文,其中双向加密又分为对如加密以及不对如加密。对如加密是据多少使用者要具有一致的密钥才得拓展加密解密,就比如大家一块约定了一样组暗号一样,对如加密底一手发生DES、3DES、AES、IDEA、RC4、RC5等;而非对如加密针锋相对于对如加密而言,无需有同一组密钥,它是同种“信息公开的密钥交换协议”。非对如加密待公开密钥和私密钥两组密钥,公开密钥和个人密钥是配对起来的,也就是说使用公开密钥进行数据加密,只有对应之私家密钥才会拓展解密。此类的加密手段来RSA、DSA等。

1.1 md5

String text = "hello,md5";
DigestUtils.md5Hex(text);

 

1.2 sha1

String text = "hello,sha1";
DigestUtils.sha1Hex(text);

 

1.3 base64

用于加密的明必须是字节数组(byte[]),加解密算法可以回到字节数组(byte[])和字符串(String)两种植格式的多寡。

//明文
String text="hello,base64";
byte[] byteArray= text.getBytes(Charset.forName("utf-8"));

//明文加密-->密文
byte[] encryptedData = Base64.encodeBase64(byteArray);
//密文解密-->明文
byte[] decryptedData = Base64.decodeBase64(encryptedData);


//明文加密-->密文
String encryptedString = Base64.encodeBase64String(byteArray);
//密文解密-->明文
String decryptedString =Base64.decodeBase64(encryptedString);

 

初识3DES

2.AES对如加密


2.1 代码

/***
 * AES加解密
 *
 * @author svili
 * @date 2017年9月8日
 *
 */
public class AESUtil {

    private static class GeneratorHolder {

        /** AES秘钥生成器 */
        private static KeyGenerator keyGenerator;

        static {
            // 静态内部类实现单例模式
            try {
                keyGenerator = KeyGenerator.getInstance("AES");
            } catch (NoSuchAlgorithmException e) {
                LogUtil.error("KeyGenerator fro AES init error.", e);
            }
            // AES秘钥长度:128bit(位)=16byte(字节)
            keyGenerator.init(128);
        }
    }

    public static KeyGenerator getGenerator() {
        return GeneratorHolder.keyGenerator;
    }

    public static byte[] generateKey() {
        SecretKey secretKey = getGenerator().generateKey();
        return secretKey.getEncoded();
    }

    public static byte[] encrypt(byte[] data, byte[] encodedKey)
            throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        // 初始化加密算法
        SecretKeySpec keySpec = new SecretKeySpec(encodedKey, "AES");
        Cipher cipher = getCipher();

        cipher.init(Cipher.ENCRYPT_MODE, keySpec);

        // 加密
        return cipher.doFinal(data);

    }

    public static byte[] decrypt(byte[] data, byte[] encodedKey)
            throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        // 初始化解密算法
        SecretKeySpec keySpec = new SecretKeySpec(encodedKey, "AES");
        Cipher cipher = getCipher();

        cipher.init(Cipher.DECRYPT_MODE, keySpec);
        // 解密
        return cipher.doFinal(data);
    }

    public static Cipher getCipher() {
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        } catch (NoSuchAlgorithmException e) {

        } catch (NoSuchPaddingException e) {

        }
        return cipher;
    }

}

2.2 测试代码

     
     //生成秘钥
     byte[] key = AESUtil.generateKey();

        // 明文
        String text = "hello , AES";
        // 密文
        byte[] encrypted = AESUtil.encrypt(text.getBytes(), key);

        System.out.println(new String(encrypted, CharsetConstants.UTF_8));

        // 解密密文-->明文
        byte[] decrypted = AESUtil.decrypt(encrypted, key);

        System.out.println(new String(decrypted, CharsetConstants.UTF_8));

 

    3DES,中文名“三重复数加密算法”, 也称3DESede或者TripleDES,是三再数量加密,且可以逆推的一致种算法方案。

3.RSA非对准如加密

    1975年美国IBM公司打响研究并宣布了DES加密算法,但DES密码长度容易给暴力破解,通过对DES算法进行改良,针对每个数据块进行
       三软DES加密,也就算是3DES加密算法。

3.1 代码

/***
 * RSA加解密</br>
 * <ul>
 * RSA数据加解密方式
 * <li>1.明文-->公钥加密-->密文-->私钥解密-->明文
 * <li>2.明文-->私钥加密-->密文-->公钥解密-->明文
 * <ul>
 * SRA密钥说明
 * <li>相关参数:公钥指数publicExponent,私钥指数privateExponent,模值modulus
 * <li>key = fun(modulus,exponent) {@link #getPublicKey(BigInteger, BigInteger)}
 * <li>key = fun(encodedKey) {@link #getPublicKey(byte[])}
 *
 * @author svili
 * @date 2017年9月8日
 *
 */
public class RSAUtil {

    /** RSA密文长度:128byte(字节) */
    private final static int DECRYPT_BLOCK_CAPACITY = 2 << 6;

    /** RSA明文长度:117byte(字节),padding=11byte(字节) */
    private final static int ENCRYPT_BLOCK_CAPACITY = (2 << 6) - 11;

    private static class GeneratorHolder {

        /** RSA秘钥生成器 */
        private static KeyPairGenerator keyPairGenerator;

        static {
            // 静态内部类实现单例模式
            try {
                keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            } catch (NoSuchAlgorithmException e) {
                keyPairGenerator = null;
                LogUtil.error("KeyGenerator fro RSA init error.", e);
            }
            // 模值长度
            keyPairGenerator.initialize(1024);
        }
    }

    public static KeyPairGenerator getGenerator() {
        return GeneratorHolder.keyPairGenerator;
    }

    public static KeyPair generateKeyPair() {
        // 生成密钥对
        return getGenerator().generateKeyPair();
    }

    public static Cipher getCipher() {
        Cipher cipher = null;
        try {
            // 算法/模式/填充
            cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        } catch (NoSuchAlgorithmException e) {

        } catch (NoSuchPaddingException e) {

        }
        return cipher;
    }

    /***
     * 加密/解密算法 </br>
     * <ul>
     * RSA算法中,对明文/密文的字节长度有所限制,超过最大长度需要分段处理.
     * <li>密文最大字节长度为:{@value #DECRYPT_BLOCK_CAPACITY}
     * <li>明文最大字节长度为:{@value #ENCRYPT_BLOCK_CAPACITY}
     * 
     * @param blockCapacity
     *            块的容量(最大字节长度)
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    private static byte[] doFinalInternal(byte[] data, Cipher cipher, int blockCapacity)
            throws IllegalBlockSizeException, BadPaddingException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(2 << 6);

        int offset = 0;
        int waitResolveLength = 0;

        while ((waitResolveLength = data.length - offset) > 0) {
            byte[] resolved;
            if (waitResolveLength < blockCapacity) {
                resolved = cipher.doFinal(data, offset, waitResolveLength);
            } else {
                resolved = cipher.doFinal(data, offset, blockCapacity);
            }

            try {
                outputStream.write(resolved);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            offset += blockCapacity;
        }

        return outputStream.toByteArray();
    }

    /**
     * 数据加密
     * 
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * 
     */
    public static byte[] encrypt(byte[] data, Key key)
            throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {

        Cipher cipher = getCipher();
        // 加密模式
        cipher.init(Cipher.ENCRYPT_MODE, key);
        // 执行加密算法
        return doFinalInternal(data, cipher, ENCRYPT_BLOCK_CAPACITY);

    }

    /**
     * 数据解密
     * 
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * 
     */
    public static byte[] decrypt(byte[] data, Key key)
            throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {

        Cipher cipher = getCipher();
        cipher.init(Cipher.DECRYPT_MODE, key);

        return doFinalInternal(data, cipher, DECRYPT_BLOCK_CAPACITY);

    }

    public static PublicKey getPublicKey(BigInteger modulus, BigInteger exponent)
            throws NoSuchAlgorithmException, InvalidKeySpecException {

        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(keySpec);
    }

    public static PrivateKey getPrivateKey(BigInteger modulus, BigInteger exponent)
            throws NoSuchAlgorithmException, InvalidKeySpecException {

        RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(modulus, exponent);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }

    public static PublicKey getPublicKey(byte[] encodedKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        // X509
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(keySpec);
    }

    public static PrivateKey getPrivateKey(byte[] encodedKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        // PKCS8
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }

}

    但出于3DES的算法是当众的,所以算法本身没什么秘密可言,主要借助唯一密钥来确保数量加密解密的安。

3.2 测试代码

public static void test1() throws Exception {
        KeyPair keyPair = RSAUtil.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        // 明文
        String text = "hello , AES";
        // 公钥加密明文-->密文
        byte[] encrypted = RSAUtil.encrypt(text.getBytes(), publicKey);

        // 私钥解密密文-->明文
        byte[] decrypted = RSAUtil.decrypt(encrypted, privateKey);

        System.out.println(new String(decrypted, CharsetConstants.UTF_8));
    }

    public static void test2() throws Exception {
        KeyPair keyPair = RSAUtil.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        // 明文
        String text = "hello , AES";

        PublicKey publicKey2 = RSAUtil.getPublicKey(publicKey.getModulus(), publicKey.getPublicExponent());
        // 公钥加密明文-->密文
        byte[] encrypted = RSAUtil.encrypt(text.getBytes(), publicKey2);

        PrivateKey privateKey2 = RSAUtil.getPrivateKey(privateKey.getModulus(), privateKey.getPrivateExponent());

        // 私钥解密密文-->明文
        byte[] decrypted = RSAUtil.decrypt(encrypted, privateKey2);

        System.out.println(new String(decrypted, CharsetConstants.UTF_8));
    }

    public static void test3() throws Exception {
        KeyPair keyPair = RSAUtil.generateKeyPair();
        PublicKey publicKey = RSAUtil.getPublicKey(keyPair.getPublic().getEncoded());
        PrivateKey privateKey = RSAUtil.getPrivateKey(keyPair.getPrivate().getEncoded());
        // 明文
        String text = "hello , AES";

        // 公钥加密明文-->密文
        byte[] encrypted = RSAUtil.encrypt(text.getBytes(), publicKey);

        // 私钥解密密文-->明文
        byte[] decrypted = RSAUtil.decrypt(encrypted, privateKey);

        System.out.println(new String(decrypted, CharsetConstants.UTF_8));
    }

 

    有人也许会见咨询,那3DES到底安不安全啊?!目前为止,还没有丁会破解3DES,所以若如果能破解它,都可以震惊整个信息安全界了……

 

 

 

原理


应用 3 条 56 位的密钥对数码进行三坏加密。3DES(即 Triple DES)是 DES 向
AES 过渡的加密算法(NIST 将 3-DES 指定为搭的加密标准)。

那个现实贯彻如下:设 Ek() 和 Dk() 代表 DES 算法的加密和解密过程,K 代表
DES 算法使用的密钥,P 代表公开,C 代表密文,这样:

3DES 加密过程吧:C = Ek3 ( Dk2 ( Ek1 ( P ) ) )

3DES 解密过程也:P = Dk1 ( EK2 ( Dk3 ( C ) ) )

 

 

 

Java以3DES加密解密之流程


 
 ①传诵共同约定的密钥(keyBytes)以及算法(Algorithm),来构建SecretKey密钥对象

        SecretKey deskey = new SecretKeySpec(keyBytes, Algorithm);    
  keyBytes必须是24字节

    ②冲算法实例化Cipher对象。它担负加密/解密

        Cipher c1 = Cipher.getInstance(Algorithm);    

    ③招称加密/解密模式及SecretKey密钥对象,实例化Cipher对象

        c1.init(Cipher.ENCRYPT_MODE, deskey);    

    ④传染切字节数组,调用Cipher.doFinal()方法,实现加密/解密,并回一个byte字节数组

        c1.doFinal(src);

 

24个解密串(必须是24员)


  3DES的密钥必须是24号的byte数组

     随便将一个String.getBytes()是老大的,会报如下错误

        java.security.InvalidKeyException: Invalid key length: 59 bytes

    解决方式有成千上万

      ①随密钥固定长度还定义字符串;

     
②先行将字符串用Base64或者MD5加密,然后截取固定长度的字符转成byte数组;

     
③字符串转成Byte数组,针对该数组开展改动,若长度过长则光截取一组成部分,若长度不够则上零

 

 

 

 

JAVA代码实现

 /**
 * SecretUtils {3DES加密解密的工具类 }
 * @author William
 * @date 2013-04-19
 */
public class SecretUtils {

    //定义加密算法,有DES、DESede(即3DES)、Blowfish
    private static final String Algorithm = "DESede";    
    private static final String PASSWORD_CRYPT_KEY = "2012PinganVitality075522628888ForShenZhenBelter075561869839";


    /**
     * 加密方法
     * @param src 源数据的字节数组
     * @return 
     */
    public static byte[] encryptMode(byte[] src) {
        try {
             SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm);    //生成密钥
             Cipher c1 = Cipher.getInstance(Algorithm);    //实例化负责加密/解密的Cipher工具类
             c1.init(Cipher.ENCRYPT_MODE, deskey);    //初始化为加密模式
             return c1.doFinal(src);
         } catch (java.security.NoSuchAlgorithmException e1) {
             e1.printStackTrace();
         } catch (javax.crypto.NoSuchPaddingException e2) {
             e2.printStackTrace();
         } catch (java.lang.Exception e3) {
             e3.printStackTrace();
         }
         return null;
     }


    /**
     * 解密函数
     * @param src 密文的字节数组
     * @return
     */
    public static byte[] decryptMode(byte[] src) {      
        try {
            SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm);
            Cipher c1 = Cipher.getInstance(Algorithm);
            c1.init(Cipher.DECRYPT_MODE, deskey);    //初始化为解密模式
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (java.lang.Exception e3) {
            e3.printStackTrace();
        }
        return null;
     }


    /*
     * 根据字符串生成密钥字节数组 
     * @param keyStr 密钥字符串
     * @return 
     * @throws UnsupportedEncodingException
     */
    public static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException{
        byte[] key = new byte[24];    //声明一个24位的字节数组,默认里面都是0
        byte[] temp = keyStr.getBytes("UTF-8");    //将字符串转成字节数组

        /*
         * 执行数组拷贝
         * System.arraycopy(源数组,从源数组哪里开始拷贝,目标数组,拷贝多少位)
         */
        if(key.length > temp.length){
            //如果temp不够24位,则拷贝temp数组整个长度的内容到key数组中
            System.arraycopy(temp, 0, key, 0, temp.length);
        }else{
            //如果temp大于24位,则拷贝temp数组24个长度的内容到key数组中
            System.arraycopy(temp, 0, key, 0, key.length);
        }
        return key;
    } 
}

测试代码

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        String msg = "3DES加密解密案例";
        System.out.println("【加密前】:" + msg);

        //加密
        byte[] secretArr = SecretUtils.encryptMode(msg.getBytes());    
        System.out.println("【加密后】:" + new String(secretArr));

        //解密
        byte[] myMsgArr = SecretUtils.decryptMode(secretArr);  
        System.out.println("【解密后】:" + new String(myMsgArr));
    }
}

参考资料


3DES在线测试工具:http://www.seacha.com/tools/3des.php

 

 

 

【密码学常因此术语】

    明文:未加密的数码

    密文:明文经过加密后的数额

    加密:将公开转换为密文的进程

    解密:将密文转换为明的历程    

    加密算法:将公开转换为密文的更换算法        

    解密算法:将密文转换为公开的转换算法

    加密密钥:用于加密算法进行加密操作的密钥

    解密密钥:用于解密算法进行解密操作的密钥

  

  本文demo下载处:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=300​

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相关文章

admin

网站地图xml地图