美文网首页
聊聊java的java.security.egd

聊聊java的java.security.egd

作者: go4it | 来源:发表于2023-08-17 09:11 被阅读0次

    本文主要研究一下java的java.security.egd

    SunEntries

    /Library/Java/JavaVirtualMachines/temurin-8.jdk/Contents/Home/src.zip!/sun/security/provider/SunEntries.java

        // name of the *System* property, takes precedence over PROP_RNDSOURCE
        private final static String PROP_EGD = "java.security.egd";
        // name of the *Security* property
        private final static String PROP_RNDSOURCE = "securerandom.source";
    
        final static String URL_DEV_RANDOM = "file:/dev/random";
        final static String URL_DEV_URANDOM = "file:/dev/urandom";
    
        private static final String seedSource;
    
        static {
            seedSource = AccessController.doPrivileged(
                    new PrivilegedAction<String>() {
    
                @Override
                public String run() {
                    String egdSource = System.getProperty(PROP_EGD, "");
                    if (egdSource.length() != 0) {
                        return egdSource;
                    }
                    egdSource = Security.getProperty(PROP_RNDSOURCE);
                    if (egdSource == null) {
                        return "";
                    }
                    return egdSource;
                }
            });
        }
    

    这里优先读取java.security.egd,如果没有设置则读取$JAVA_HOME/jre/lib/security/java.security文件中的securerandom.source配置,默认值为file:/dev/random

    SeedGenerator

    /Library/Java/JavaVirtualMachines/temurin-8.jdk/Contents/Home/src.zip!/sun/security/provider/SeedGenerator.java

        // Static initializer to hook in selected or best performing generator
        static {
            String egdSource = SunEntries.getSeedSource();
    
            /*
             * Try the URL specifying the source (e.g. file:/dev/random)
             *
             * The URLs "file:/dev/random" or "file:/dev/urandom" are used to
             * indicate the SeedGenerator should use OS support, if available.
             *
             * On Windows, this causes the MS CryptoAPI seeder to be used.
             *
             * On Solaris/Linux/MacOS, this is identical to using
             * URLSeedGenerator to read from /dev/[u]random
             */
            if (egdSource.equals(SunEntries.URL_DEV_RANDOM) ||
                    egdSource.equals(SunEntries.URL_DEV_URANDOM)) {
                try {
                    instance = new NativeSeedGenerator(egdSource);
                    if (debug != null) {
                        debug.println(
                            "Using operating system seed generator" + egdSource);
                    }
                } catch (IOException e) {
                    if (debug != null) {
                        debug.println("Failed to use operating system seed "
                                      + "generator: " + e.toString());
                    }
                }
            } else if (egdSource.length() != 0) {
                try {
                    instance = new URLSeedGenerator(egdSource);
                    if (debug != null) {
                        debug.println("Using URL seed generator reading from "
                                      + egdSource);
                    }
                } catch (IOException e) {
                    if (debug != null) {
                        debug.println("Failed to create seed generator with "
                                      + egdSource + ": " + e.toString());
                    }
                }
            }
    
            // Fall back to ThreadedSeedGenerator
            if (instance == null) {
                if (debug != null) {
                    debug.println("Using default threaded seed generator");
                }
                instance = new ThreadedSeedGenerator();
            }
        }
    

    如果是file:/dev/randomfile:/dev/urandom则走NativeSeedGenerator,不是则走URLSeedGenerator,为空则走ThreadedSeedGenerator

    NativeSeedGenerator

    /**
     * Native seed generator for Unix systems. Inherit everything from
     * URLSeedGenerator.
     *
     */
    class NativeSeedGenerator extends SeedGenerator.URLSeedGenerator {
    
        NativeSeedGenerator(String seedFile) throws IOException {
            super(seedFile);
        }
    
    }
    

    NativeSeedGenerator继承了URLSeedGenerator

    SecureRandomSpi

    NativePRNG

    /Library/Java/JavaVirtualMachines/temurin-8.jdk/Contents/Home/src.zip!/sun/security/provider/NativePRNG.java

    public final class NativePRNG extends SecureRandomSpi {
    
        private static final long serialVersionUID = -6599091113397072932L;
    
        private static final Debug debug = Debug.getInstance("provider");
    
        // name of the pure random file (also used for setSeed())
        private static final String NAME_RANDOM = "/dev/random";
        // name of the pseudo random file
        private static final String NAME_URANDOM = "/dev/urandom";
    
        // which kind of RandomIO object are we creating?
        private enum Variant {
            MIXED, BLOCKING, NONBLOCKING
        }
    
        // singleton instance or null if not available
        private static final RandomIO INSTANCE = initIO(Variant.MIXED);
    
        /**
         * Get the System egd source (if defined).  We only allow "file:"
         * URLs for now. If there is a egd value, parse it.
         *
         * @return the URL or null if not available.
         */
        private static URL getEgdUrl() {
            // This will return "" if nothing was set.
            String egdSource = SunEntries.getSeedSource();
            URL egdUrl;
    
            if (egdSource.length() != 0) {
                if (debug != null) {
                    debug.println("NativePRNG egdUrl: " + egdSource);
                }
                try {
                    egdUrl = new URL(egdSource);
                    if (!egdUrl.getProtocol().equalsIgnoreCase("file")) {
                        return null;
                    }
                } catch (MalformedURLException e) {
                    return null;
                }
            } else {
                egdUrl = null;
            }
    
            return egdUrl;
        }
    
        //......
    }    
    

    NativePRNG的getEgdUrl则通过egdSource来构建URL

    小结

    • SunEntries优先读取java.security.egd,如果没有设置则读取$JAVA_HOME/jre/lib/security/java.security文件中的securerandom.source配置,默认值为file:/dev/random
    • SeedGenerator判断egdSource如果是file:/dev/randomfile:/dev/urandom则走NativeSeedGenerator,不是则走URLSeedGenerator,为空则走ThreadedSeedGenerator
    • 至于/dev/./urandom这种表示看起来比较困惑,翻译过来就是是/dev当前目录下的unrandom,其实就是/dev/urandom,之所以有这种传参主要是早期jdk版本有个bug,没有给NativeSeedGenerator传参,所以通过file:/dev/./urandom绕过这个bug

    doc

    相关文章

      网友评论

          本文标题:聊聊java的java.security.egd

          本文链接:https://www.haomeiwen.com/subject/dmwlmdtx.html