zoukankan      html  css  js  c++  java
  • 关于 java中的SecureRandom在linux中每次生成不同结果

    使用AES算法的时候,会发现下面的代码在windows每次产生确定的结果,但Linux就不同,导致无法正确解密

    public static String encrypt(String content, String password) {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(password.getBytes()));
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES");// 创建密码器
            byte[] byteContent = content.getBytes("utf-8");
            cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
            byte[] result = cipher.doFinal(byteContent);
    
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            random.setSeed(password.getBytes());
            kgen.init(128, random);
    
            return parseByte2HexStr(result); // 加密
        } catch (Exception e) {
            System.out.print(e);
        }
        return null;
    }

    原因在于加红的部分SecureRaom的生成,Linux下默认的算法是“NativePRNG”, 而windows下默认是“SHA1PRNG”(sun提供的算法)

    对于这两种算法

    相同点:
      1. 都是伪随即算法,
      2. 默认都是阻塞式
    
    不同点:
      1. SHA1PRNG使用的seed是在系统启动时就指定的,而NativePRNG会在内核中随机取得(这也是Linux下每次结果不同的原因)
      2. 正是因为每次随机取,NativePRNG开销要更大些

     虽然Linux认为最佳随机算法是NativePRNG(安全因素),但使用每次都变化的radom是无法正确解密的,所以并不适用于此种场合。

    解决办法

    SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
    secureRandom.setSeed(password.getBytes());
    kgen.init(128, secureRandom);

    另外,这两种算法都是阻塞式算法,会读取/var/random,如果想非阻塞,启动时加上下面参数

    Djava.security=file:/dev/urandom

    参考:

    http://www.cjsdn.net/Doc/JDK50/java/security/SecureRandom.html

    https://docs.oracle.com/javase/7/docs/api/java/security/SecureRandom.html

    http://calvin1978.blogcn.com/articles/securerandom.html

    https://stackoverflow.com/questions/27622625/securerandom-with-nativeprng-vs-sha1prng

    ---栖息之鹰(一个外表懒洋洋的内心有激情的程序员) 此博客为笔者原著,转载时请注明出处,谢谢!
  • 相关阅读:
    我的不足
    对于大数据的一些思考
    对于三层架构的理解
    面试的那些事
    最前端资源汇总——摘自张果博客
    ES6_Promise 对象 阮一锋
    深入理解ES6箭头函数的this以及各类this面试题总结
    函数的扩展——箭头函数this的使用
    ES6学习总结 (二)
    原生js的ajax请求
  • 原文地址:https://www.cnblogs.com/roostinghawk/p/8384057.html
Copyright © 2011-2022 走看看