以前听说技术是做时间长了,通过度娘可以写一个价值高昂的项目,但是经过这两天解决 ASC 加密问题发现自己身上的问题。
1. 分析问题能力和查看问题的能力还差很多。
2. 太依赖度娘导致自己的基础知识不扎实。

记录一下问题的过程,希望在茫茫网络中找到方案:
1. 因为需求要求需要做一个加密的算法对数据进行加密,所以在度娘上找到一个 aws 加密,代码如下:

package com.baichanhui.project;

import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESUtil5 {

    private static final String CipherMode = "AES/CBC/PKCS5Padding";
    private static final String DEFAULST_SECURITY_KEY = "XXX-123-!@#$%^&*()_+=,./";
    private static final String encodFormat = "UTF-8";

    private static SecretKeySpec createKey(String key) {
        key = key == null ? "" : key;
        StringBuilder sb = new StringBuilder(16);
        sb.append(key);
        while (sb.length() < 16) {
            sb.append("0");
        }
        if (sb.length() > 16) {
            sb.setLength(16);
        }

        byte[] data = null;
        try {
            data = sb.toString().getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return new SecretKeySpec(data, "AES");
    }

    private static IvParameterSpec createIV(String password) {
        password = password == null ? "" : password;
        StringBuilder sb = new StringBuilder(16);
        sb.append(password);
        while (sb.length() < 16) {
            sb.append("0");
        }
        if (sb.length() > 16) {
            sb.setLength(16);
        }

        byte[] data = null;
        try {
            data = sb.toString().getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return new IvParameterSpec(data);
    }

    
    public static byte[] aes128CBCEncrypt(byte[] content, String password, String iv) {
        try {
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.ENCRYPT_MODE, createKey(password), createIV(iv));
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] aes128CBCDecrypt(byte[] content, String password, String iv) {
        try {
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.DECRYPT_MODE, createKey(password), createIV(iv));
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String encrypt(String content) {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(DEFAULST_SECURITY_KEY.getBytes(encodFormat)));
            byte[] bytes = kgen.generateKey().getEncoded();
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(bytes, "AES"));
            byte[] result = cipher.doFinal(content.getBytes(encodFormat));
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < result.length; i++) {
                String hex = Integer.toHexString(result[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String encrypt(String content, String key) {
        if (isEmpty(key)) {
            return encrypt(content);
        }
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(key.getBytes(encodFormat)));
            byte[] bytes = kgen.generateKey().getEncoded();
            System.out.println("key === " + Arrays.toString(bytes));
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(bytes, "AES"));
            byte[] result = cipher.doFinal(content.getBytes(encodFormat));
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < result.length; i++) {
                String hex = Integer.toHexString(result[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
    
    public static String decrypt(String content, String securityKey) {

        if (isEmpty(securityKey)) {
            return decrypt(content);
        }
        byte[] bytes = new byte[content.length() / 2];
        for (int i = 0; i < content.length() / 2; i++) {
            int high = Integer.parseInt(content.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(content.substring(i * 2 + 1, i * 2 + 2), 16);
            bytes[i] = (byte) (high * 16 + low);
        }
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
//            kgen.init(128, new SecureRandom(hexStringToBytes(securityKey)));
            kgen.init(128, new SecureRandom(hexStringToBytes(securityKey)));
            SecretKey secretKey = kgen.generateKey();
            SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            byte[] result = cipher.doFinal(bytes);
            return new String(result);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static String decrypt(String content) {
        if (isEmpty(content)) {
            return null;
        }
        byte[] bytes = new byte[content.length() / 2];
        for (int i = 0; i < content.length() / 2; i++) {
            int high = Integer.parseInt(content.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(content.substring(i * 2 + 1, i * 2 + 2), 16);
            bytes[i] = (byte) (high * 16 + low);
        }
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(DEFAULST_SECURITY_KEY.getBytes()));
            SecretKey secretKey = kgen.generateKey();
            SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            byte[] result = cipher.doFinal(bytes);
            return new String(result);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    private static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }
    
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    public static void main(String... args) throws UnsupportedEncodingException {
        String keyEncodeString = AESUtil5.encrypt("");
        System.out.println("keyEncodeString"+keyEncodeString);
        String eKey = AESUtil5.decrypt(keyEncodeString, "");
        System.out.println("decrypt"+eKey);
    }

}

这段代码中在windows 中运行没有任何异常,但是在linux中出现问题,每次生成的加密数据都是不一致的。因为这段代码中因为使用了下面的这个对象,会使用linux本身的随机数作为种子,但是这个种子是不可逆的。

kgen.init(128, new SecureRandom(DEFAULST_SECURITY_KEY.getBytes()));

2.修改后的代码是:

           *  注意这里是修改后的代码
           */
           SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
           random.setSeed(AEC_ENCODE_RULES.getBytes());
           keygen.init(128, random);

这样就没问题了,解决了新数据的问题。

但是!但是 ! 但是 !
我的老数据怎么反解密回来我没找到方法。因为老数据用的是第一中加密方式,而第一种加密方式的种子在我反解密的时候生成的种子是和加密之前的不一致,导致我的老数据没有办法进行反向的解密。
希望能够提供一些思路,必有重谢!!!!!

你可能感兴趣的:(痛)