DES加密在linux下的问题

最近写了段DES加密的代码

    // 指定DES加密解密所用的秘钥
    private static Key key;
    private static String KEY_STR = "dashuaigege19931130";
    static {
        try {
            KeyGenerator generator = KeyGenerator.getInstance("DES");
            generator.init(new SecureRandom(KEY_STR.getBytes()));
            key = generator.generateKey();
            generator = null;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 对字符串进行DES加密,返回BASE64编码的加密字符串
    public static String getEncryptString(String str) {
        Base64 base64 = new Base64();
        try {
            byte[] strBytes = str.getBytes("UTF8");
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] encryptStrBytes = cipher.doFinal(strBytes);
            return base64.encodeToString(encryptStrBytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 对BASE64编码的加密字符串进行解密,返回解密后的字符串
    public static String getDecryptString(String str) {
        Base64 base64 = new Base64();
        try {
            byte[] strBytes = base64.decode(str);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] decryptStrBytes = cipher.doFinal(strBytes);
            return new String(decryptStrBytes, "UTF8");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

在windows环境下完美运行。但是当我把程序移到linux下的到时候,就报错了
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
这里写图片描述
看堆栈是解密的时候报错了。经过检查,其实与解密问题,问题出现在了生成Key的时候。
再来看下这段代码

KeyGenerator generator = KeyGenerator.getInstance("DES");
            generator.init(new SecureRandom(KEY_STR.getBytes()));
            key = generator.generateKey();
            generator = null;

问题就出在 new SecureRandom(KEY_STR.getBytes()) 上。SecureRandom类提供加密的强随机数生成器,在windows环境下每次都将会生成相同的Key值。但是在linux环境下则不同,SecureRandom尝试实现完全随机化的内部状态。因此可以对其指定算法名称

SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );

系统将确定环境中是否有其所请求的算法,是否有多个,是否去首选实现。
其次再调用

 secureRandom.setSeed(strKey.getBytes());

这样就能生成固定的Key值
因此,可改为如下代码:

try {
            KeyGenerator generator = KeyGenerator.getInstance("DES");
            SecureRandom secureRandom=SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(KEY_STR.getBytes());
            generator.init(secureRandom);
            key = generator.generateKey();
            generator = null;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

参考https://wenku.baidu.com/view/b968921514791711cc791778.html

你可能感兴趣的:(Java)