CLOVERšŸ€

That was when it all began.

SecureRandomć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠ćŖć©ć«é–¢ć™ć‚‹ęƒ…å ±ć‚’ć”ć‚ƒć‚“ćØ見悋

恓悌ćÆ态ćŖć«ć‚’ć—ćŸćć¦ę›øć„ćŸć‚‚ć®ļ¼Ÿ

Javać®ęš—å·ē”Øć®ä¹±ę•°ć‚øć‚§ćƒćƒ¬ćƒ¼ć‚æćƒ¼ļ¼ˆRNG / Random Number Generatorļ¼‰ćØ恗恦态ćØć¦ć‚‚ć‚ˆćä½æ悏悌悋SecureRandom恧恙恌怂

SecureRandom (Java SE 11 & JDK 11 )

ć“ć“ć§ęŒ‡å®šć•ć‚Œć‚‹ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠ćŖć©ć®ęƒ…å ±ć‚’ć€ć‚ć‚“ć¾ć‚Šć”ć‚ƒć‚“ćØč¦‹ćŸć“ćØ恌ćŖ恄ćŖ恁ćØę€ć„ć¾ć—ć¦ć€‚

1åŗ¦ć€čŖæć¹ć¦ćæ悈恆恋ćØ怂

ć”ć‚‡ć£ćØ恠恑怂

ē’°å¢ƒ

ä»Šå›žć®ē’°å¢ƒćÆ态恓恔悉恧恙怂

$ java --version
openjdk 11.0.9.1 2020-11-04
OpenJDK Runtime Environment (build 11.0.9.1+1-Ubuntu-0ubuntu1.20.04)
OpenJDK 64-Bit Server VM (build 11.0.9.1+1-Ubuntu-0ubuntu1.20.04, mixed mode, sharing)


$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.1 LTS
Release:    20.04
Codename:   focal


$ uname -srvmpio
Linux 5.4.0-58-generic #64-Ubuntu SMP Wed Dec 9 08:16:25 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Java 11态Ubuntu Linux 20.04恧恙怂

SecureRandom

SecureRandom恮Javadoc悒見恦ćæ悋ćØć€ę¬”ć®ć‚ˆć†ć«ę›øć„ć¦ć„ć¾ć™ć€‚

ęš—å·ē”Øć«å¼·åŒ–ć•ć‚ŒćŸä¹±ę•°ć‚øć‚§ćƒćƒ¬ćƒ¼ć‚æļ¼ˆRNGļ¼‰ć‚’ęä¾›ć™ć‚‹

SecureRandom())

強力ćŖęš—å·åŒ–ć«ć‚ˆć‚‹ä¹±ę•°ćÆ态FIPS 140-2, Security Requirements for Cryptographic Modules恮悻ć‚Æć‚·ćƒ§ćƒ³4.9.1ć«ęŒ‡å®šć•ć‚Œć¦ć„ć‚‹ēµ±č؈ēš„ä¹±ę•°ē”Ÿęˆćƒ†ć‚¹ćƒˆć«ęœ€ä½Žé™é©åˆć—ć¦ć„ć¾ć™ć€‚

FIPS 140-2, Security Requirements for Cryptographic Modules

恕悉恫态SecureRandomćÆ态非ę±ŗå®šč«–ēš„ćŖå‡ŗåŠ›ć‚’ē”Ÿęˆć™ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚ ć—ćŸćŒć£ć¦ć€SecureRandomć‚Ŗ惖ć‚ø悧ć‚Æ惈恫ęø”ć•ć‚Œć‚‹ć‚·ćƒ¼ćƒ‰ęę–™ćÆć™ć¹ć¦äŗˆęø¬äøåÆčƒ½ć§ćŖ恑悌恰ćŖć‚‰ćšć€ć™ć¹ć¦ć®SecureRandomå‡ŗåŠ›ć‚·ćƒ¼ć‚±ćƒ³ć‚¹ćÆ态怌RFC 4086: ć‚»ć‚­ćƒ„ćƒŖćƒ†ć‚£ć®ćƒ©ćƒ³ćƒ€ćƒ ę€§č¦ä»¶ć€ć§čŖ¬ę˜Žć•ć‚Œć¦ć„ć‚‹ć‚ˆć†ć«ć€ęš—å·ēš„ć«å¼·ććŖ恑悌恰ćŖć‚Šć¾ć›ć‚“ć€‚

Randomness Requirements for Security

ć¾ćŸć€SecureRandomć®ć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ćÆ态ē‰¹å®šć®ä¹±ę•°ē”Ÿęˆć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠悒ä½æē”Øć—ć¦ä¹±ę•°ć‚’ē”Ÿęˆć—ć¾ć™ć€‚

ć“ć®ä¹±ę•°ē”Ÿęˆć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ć§ć™ćŒć€ć„ćć¤ć‹ć®åå‰ć“ćč¦‹ć‚‹ć‚‚ć®ć®ć€ćć®äø€č¦§ć£ć¦ć©ć“ć«ć‚ć‚‹ć‚“ć ć‚ć†ļ¼ŸćØę€ć£ć¦ć„ćŸć‚‰ć€
恓恔悉悂Javadocć‹ć‚‰ćŸć©ć‚Œć¾ć™ć­ć€‚

f:id:Kazuhira:20201225003243p:plain

Javać‚»ć‚­ćƒ„ćƒŖćƒ†ć‚£ęؙęŗ–ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ åęŒ‡å®š / SecureRandomä¹±ę•°ē”Ÿęˆć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠

SecureRandom恧ä½æćˆć‚‹ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠

恧ćÆ态SecureRandom恧ä½æē”Øć§ćć‚‹ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ć‚’ć‚‚ć†ć”ć‚‡ć£ćØč¦‹ć¦ć„ćć¾ć—ć‚‡ć†ć€‚

Java 11恧ćÆ态仄äø‹ć®7ć¤ć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠恌恂悋悈恆恧恙怂

ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ å čŖ¬ę˜Ž
NativePRNG ćƒć‚¤ćƒ†ć‚£ćƒ–OSć‹ć‚‰ä¹±ę•°ć‚’å–å¾—ć™ć‚‹ć€‚ä¹±ę•°ē”Ÿęˆć®ćƒ–ćƒ­ćƒƒć‚Æꀧ恫恤恄恦ćÆä½•ć‚‚č”Ø꘎恕悌ćŖ恄
NativePRNGBlocking ćƒć‚¤ćƒ†ć‚£ćƒ–OSć‹ć‚‰ä¹±ę•°ć‚’å–å¾—ć—ć€åæ…要恫åæœć˜ć¦ćƒ–ćƒ­ćƒƒć‚Æ恙悋
NativePRNGNonBlocking ćƒć‚¤ćƒ†ć‚£ćƒ–OSć‹ć‚‰ä¹±ę•°ć‚’å–å¾—ć™ć‚‹ćŒć€ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć®é€Ÿåŗ¦ä½Žäø‹ć‚’éæć‘ć‚‹ćŸć‚ć«ćƒ–ćƒ­ćƒƒć‚Æ恗ćŖ恄
PKCS11 ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ęøˆćŠć‚ˆć³ę§‹ęˆęøˆć®PKCS#11ćƒ©ć‚¤ćƒ–ćƒ©ćƒŖć‹ć‚‰ä¹±ę•°ć‚’å–å¾—ć™ć‚‹
DRBG NIST SP 800-90Ar1ć§å®šē¾©ć•ć‚Œć¦ć„ć‚‹DRBGćƒ”ć‚«ćƒ‹ć‚ŗ惠悒ä½æē”Ø恗恦SUNćƒ—ćƒ­ćƒć‚¤ćƒ€ć‹ć‚‰ęä¾›ć•ć‚ŒćŸć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠
SHA1PRNG Sunćƒ—ćƒ­ćƒć‚¤ćƒ€ćŒęä¾›ć™ć‚‹ę“¬ä¼¼ä¹±ę•°ē”Ÿęˆ(PRNG)ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠怂 ć“ć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠ćÆ态PRNG恮åŸŗē›¤ćØ恗恦SHA-1悒ä½æē”Ø恙悋
Windows-PRNG Windows OSć‹ć‚‰ä¹±ę•°ć‚’å–å¾—ć™ć‚‹

PRNGćÆ态ē–‘ä¼¼ä¹±ę•°ć‚øć‚§ćƒćƒ¬ćƒ¼ć‚æļ¼ˆPseudo Random Number Generatorļ¼‰ć§ć™ć­ć€‚

ę¬”ć«ć€ć“ć”ć‚‰ć®ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’č¦‹ć¦ć„ćć¾ć™ć€‚

Java Platform, Standard Editionセキュリティ開発者ガイド, リリース11

å„ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ć§ć©ć®ć‚ˆć†ćŖć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠恌ä½æćˆć‚‹ć®ć‹ćÆ态JDKćƒ—ćƒ­ćƒć‚¤ćƒ€ćƒ»ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’č¦‹ć‚‹ć“ćØ恫ćŖć‚Šć¾ć™ć€‚

JDKプロバイダ・ドキュメント

SecureRandomå®Ÿč£…ć«ć¤ć„ć¦ćÆ态恓恔悉怂

SecureRandomå®Ÿč£…

Solaris态Linux态macOS态Windows恧ä½æćˆć‚‹ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ćŒåˆ—ęŒ™ć•ć‚Œć¦ćŠć‚Šć€ć©ć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ćŒć©ć®ćƒ—ćƒ­ćƒć‚¤ćƒ€ćƒ¼ć«
å«ć¾ć‚Œć¦ć„ć‚‹ć‹ćŒčØ˜č¼‰ć•ć‚Œć¦ć„ć¾ć™ć€‚

恟ćØ恈恰态Linux恠ćØSUNćƒ—ćƒ­ćƒć‚¤ćƒ€ćƒ¼ć«ć‚ˆć‚‹NativePRNG态DRBG态SHA1PRNG态NativePRNGBlocking态NativePRNGNonBlocking恌
利ē”ØåÆčƒ½ć§ć™ć€‚
ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć§ćÆSHA1PRNG恌éøꊞ恕悌态java.security恮ć‚Øćƒ³ćƒˆćƒ­ćƒ”ćƒ¼åŽé›†ćƒ‡ćƒć‚¤ć‚¹ć‚’file:/dev/urandomć¾ćŸćÆfile:/dev/random恫
恙悋ćØNativePRNG恌å„Ŗå…ˆć•ć‚Œć‚‹ć‚ˆć†ć§ć™ļ¼ˆćØę›øć„ć¦ć„ć‚‹ć®ć§ć™ćŒć€ć“ć®å¾Œć§ē¢ŗčŖć—恦ćæćŸć‚‰ć€ć‚‚ć†å°‘ć—č¤‡é›‘ć§ć—ćŸļ¼‰ć€‚

SecuraRandomć«é–¢ć™ć‚‹ćƒ—ćƒ­ćƒć‚¤ćƒ€ćƒ¼ćÆ态SUN态SunPKCS11态SunMSCAPI恮3ć¤ćŒć‚ć‚‹ć‚ˆć†ć§ć™ć€‚å¾Œč€…2恤ćÆ态恝悌恞悌Solaris态
Windows恧ä½æē”Øć•ć‚Œć¾ć™ć€‚

SUN惗惭惐悤惀

SunPKCS11惗惭惐悤惀

SunMSCAPI惗惭惐悤惀

å„ćƒ—ćƒ­ćƒć‚¤ćƒ€ćƒ¼ć«ćÆ态ć‚Øćƒ³ć‚øćƒ³ćƒ»ć‚Æćƒ©ć‚¹ćØåƾåæœć™ć‚‹ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ćŒå«ć¾ć‚Œć¦ć„ć¾ć™ć€‚

ć‚Øćƒ³ć‚øćƒ³ćƒ»ć‚Æćƒ©ć‚¹ćØćÆ态SecureRandom悄MessageDigestćØć„ć£ćŸć‚‚ć®ć§ć™ć€‚

ć‚Øćƒ³ć‚øćƒ³ćƒ»ć‚Æćƒ©ć‚¹ćŠć‚ˆć³åƾåæœć™ć‚‹Service Provider Interfaceć‚Æćƒ©ć‚¹

ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠ćÆNativePRNG悄SHA-256ćØć„ć£ćŸć‚‚ć®ć§ć™ć­ć€‚

ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ć§ä½æ恈悋SecureRandomć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠ćØćƒ—ćƒ­ćƒ‘ćƒ†ć‚£ć‚’ē¢ŗčŖć™ć‚‹

ć“ć“ć§å°‘ć—ć€ć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰ć‚’ę›ø恄恦ćæć¾ć—ć‚‡ć†ć€‚

åÆ¾č±”ć®ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ć§ä½æ恈悋SecureRandomć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠ćØćƒ—ćƒ­ćƒ‘ćƒ†ć‚£ć‚’å‡ŗåŠ›ć—ć¦ćæć¾ć™ć€‚

恓悓ćŖć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰ć‚’ē”Øꄏ怂
PrintSecureRandomAlgorithms.java

import java.security.Provider;
import java.security.Security;
import java.util.Map;

public class PrintSecureRandomAlgorithms {
    public static void main(String... args) {
        System.out.println("Platform Supported SecureRandom Algorithms:");
        
        for (String algorithm : Security.getAlgorithms("SecureRandom")) {
            System.out.printf("  %s%n", algorithm);
        }

        System.out.println();

        System.out.println("SecureRandom Properties:");
        for (Provider provider : Security.getProviders()) {
            for (Map.Entry<Object, Object> entry : provider.entrySet()) {
                if (entry.getKey().toString().startsWith("SecureRandom")) {
                    System.out.printf("  [provider: %s] %s = %s%n", provider, entry.getKey(), entry.getValue());
                }
            }
        }
    }
}

ä½æē”Ø恗恦恄悋恮ćÆć€ć“ć®ć‚ćŸć‚Šć§ć™ć­ć€‚

Security (Java SE 11 & JDK 11 )

Provider (Java SE 11 & JDK 11 )

恓恓恧恮ProviderćÆć€å…ˆć»ć©ć€ŒSUN怍悄怌SunPKCS11怍ćØć„ć†åå‰ć§å‡ŗć¦ććŸćƒ—ćƒ­ćƒć‚¤ćƒ€ćƒ¼ć®ć“ćØ恧恙怂

Security#getProviders恧态ä½æē”Øć§ćć‚‹ćƒ—ćƒ­ćƒć‚¤ćƒ€ćƒ¼ć‚’ć™ć¹ć¦å–å¾—ć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚

å®Ÿč”Œć—ć¦ćæć¾ć™ć€‚

$ java PrintSecureRandomAlgorithms.java 
Platform Supported SecureRandom Algorithms:
  DRBG
  SHA1PRNG
  NATIVEPRNGBLOCKING
  NATIVEPRNGNONBLOCKING
  NATIVEPRNG

SecureRandom Properties:
  [provider: SUN version 11] SecureRandom.NativePRNG ThreadSafe = true
  [provider: SUN version 11] SecureRandom.NativePRNGNonBlocking ThreadSafe = true
  [provider: SUN version 11] SecureRandom.SHA1PRNG = sun.security.provider.SecureRandom
  [provider: SUN version 11] SecureRandom.NativePRNG = sun.security.provider.NativePRNG
  [provider: SUN version 11] SecureRandom.NativePRNGNonBlocking = sun.security.provider.NativePRNG$NonBlocking
  [provider: SUN version 11] SecureRandom.DRBG ImplementedIn = Software
  [provider: SUN version 11] SecureRandom.SHA1PRNG ThreadSafe = true
  [provider: SUN version 11] SecureRandom.SHA1PRNG ImplementedIn = Software
  [provider: SUN version 11] SecureRandom.DRBG = sun.security.provider.DRBG
  [provider: SUN version 11] SecureRandom.NativePRNGBlocking ThreadSafe = true
  [provider: SUN version 11] SecureRandom.DRBG ThreadSafe = true
  [provider: SUN version 11] SecureRandom.NativePRNGBlocking = sun.security.provider.NativePRNG$Blocking

LinuxäøŠć§å‹•ć‹ć—恦恄悋恮恧态ä½æćˆć‚‹ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠ćØ恗恦NativePRNG态DRBG态SHA1PRNG态NativePRNGBlocking态
NativePRNGNonBlocking恮5恤恌č”Øē¤ŗć•ć‚Œć¦ć„ć¾ć™ć€‚

ć¾ćŸć€ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£ćÆSecureRandom恮悂恮恧ēµžć‚Šč¾¼ć‚“ć§ć„ć¾ć™ćŒć€č”Øē¤ŗć•ć‚Œć¦ć„ć‚‹ćƒ—ćƒ­ćƒć‚¤ćƒ€ćƒ¼ćÆSUN恠恑恧恙恭怂

SecureRandomå†…ć§ć€ć©ć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠恌ä½æ悏悌悋ļ¼Ÿ

ꬔ恫态SecureRandomć®ć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć§ä½æć‚ć‚Œć‚‹ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠恮ę±ŗå®šć«ć¤ć„ć¦č¦‹ć¦ć„ćć¾ć—ć‚‡ć†ć€‚

SecureRandomć®ć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć‚’ä½œęˆć™ć‚‹ć«ćÆć€ć‚³ćƒ³ć‚¹ćƒˆćƒ©ć‚Æć‚æ悒ä½æ恆恋SecureRandom#getInstanceć§ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠悒
ęŒ‡å®šć™ć‚‹ć‹ć€ć‚‚ć—ććÆSecureRandom#getInstanceStrongć§å–å¾—ć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚

ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ć‚’ęŒ‡å®šć—ćŸå “åˆćÆć¾ć‚ć„ć„ć®ć§ć™ćŒć€ćć®ä»–ć®ę–¹ę³•ć ćØć©ć†ć„ć†ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠恌éøć°ć‚Œć‚‹ć‹ę°—ć«ćŖ悋ćØ恓悍恧恙怂

ćØ恄恆悏恑恧态恓悓ćŖć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰ć‚’ä½œć£ć¦ę”ä»¶ć‚’å¤‰ćˆćŖ恌悉ē¢ŗčŖć—恦ćæć¾ć™ć€‚
PrintSecureRandomInstanceAlgorithm.java

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class PrintSecureRandomInstanceAlgorithm {
    public static void main(String... args) throws NoSuchAlgorithmException {
        SecureRandom secureRandom;

        if (args.length > 0 && "strong".equals(args[0])) {
            secureRandom = SecureRandom.getInstanceStrong();
        } else if (args.length > 0) {
            String algorithm = args[0];
            secureRandom = SecureRandom.getInstance(algorithm);
        } else {
            secureRandom = new SecureRandom();
        }

        System.out.printf("SecureRandom Algorithm = %s%n", secureRandom.getAlgorithm());
    }
}

å¼•ę•°ć§strongćØęŒ‡å®šć™ć‚‹ćØSecureRandom#getInstanceStrong悒ä½æć„ć€ćć‚Œä»„å¤–ć®å¼•ę•°ć‚’äøŽćˆć‚‹ćØć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ć‚’ęŒ‡å®šć—ćŸ
恓ćØ恫ćŖć‚Šć€å¼•ę•°ćŖ恗恠ćØć‚³ćƒ³ć‚¹ćƒˆćƒ©ć‚Æć‚æ悒ä½æć£ć¦SecureRandomć®ć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć‚’ē”Ÿęˆć—ć¾ć™ć€‚

ē¢ŗčŖć€‚

## å¼•ę•°ćŖ恗
$ java PrintSecureRandomInstanceAlgorithm.java
SecureRandom Algorithm = NativePRNG


## SecureRandom#getInstanceStrong
$ java PrintSecureRandomInstanceAlgorithm.java strong
SecureRandom Algorithm = NativePRNGBlocking


## ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ęŒ‡å®š
$ java PrintSecureRandomInstanceAlgorithm.java DRBG
SecureRandom Algorithm = DRBG

ć“ć®ć‚ˆć†ćŖēµęžœć«ćŖć‚Šć¾ć—ćŸć€‚

SecureRandomć‚³ćƒ³ć‚¹ćƒˆćƒ©ć‚Æć‚æ悒ä½æ恆

JDKćƒ—ćƒ­ćƒć‚¤ćƒ€ćƒ»ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć«ć‚ˆć‚‹ćØ态Linuxć§ć®ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠ćÆ

ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć§ćÆSHA1PRNG恌éøꊞ恕悌态java.security恮ć‚Øćƒ³ćƒˆćƒ­ćƒ”ćƒ¼åŽé›†ćƒ‡ćƒć‚¤ć‚¹ć‚’file:/dev/urandomć¾ćŸćÆfile:/dev/random恫恙悋ćØNativePRNG恌å„Ŗå…ˆć•ć‚Œć‚‹

ćØ恄恆恓ćØć§ć—ćŸć€‚ć§ć€ä»Šå›žćÆNativePRNG恌éøꊞ恕悌恟恓ćØ恫ćŖć‚Šć¾ć™ć€‚

ćŖ恮恧态恩恓恋恧java.security恮ć‚Øćƒ³ćƒˆćƒ­ćƒ”ćƒ¼åŽé›†ćƒ‡ćƒć‚¤ć‚¹ć‚’file:/dev/urandomć¾ćŸćÆfile:/dev/randomć«ć—ć¦ć„ć‚‹ć‚ć‘ć§ć™ć­ć€‚

ć‚»ć‚­ćƒ„ćƒŖćƒ†ć‚£é–¢é€£ć®ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£ćØ恄恆ćØ态仄äø‹ć®ć©ć”悉恋恧čØ­å®šć™ć‚‹ć“ćØ恫ćŖć‚Šć¾ć™ć€‚

ć‚»ć‚­ćƒ„ćƒŖćƒ†ć‚£ćƒ»ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£

今回ćÆć‚»ć‚­ćƒ„ćƒŖćƒ†ć‚£é–¢é€£ć®ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£ćÆ态$JAVA_HOME/conf/security/java.securityćƒ•ć‚”ć‚¤ćƒ«ć§č¦‹ć¦ć„ćć“ćØć«ć—ć¾ć—ć‚‡ć†ć€‚

$JAVA_HOME/conf/security/java.securityćƒ•ć‚”ć‚¤ćƒ«å†…ć®ć€securerandom.source悒ē¢ŗčŖć—恦ćæć¾ć™ć€‚

$ grep securerandom.source /usr/lib/jvm/java-11-openjdk-amd64/conf/security/java.security | grep -v '^#'
securerandom.source=file:/dev/random

/dev/random恧恙恭怂

securerandom.sourceć‚’ć‚³ćƒ”ćƒ³ćƒˆć‚¢ć‚¦ćƒˆć—ć¦ćæć¾ć—ć‚‡ć†ć€‚

#securerandom.source=file:/dev/random

ē¢ŗčŖć€‚

$ java PrintSecureRandomInstanceAlgorithm.java
SecureRandom Algorithm = DRBG

SHA1PRNG恫ćŖ悋ćØę€ć£ć¦ć„ćŸć®ć§ć™ćŒć€DRBG恫ćŖć‚Šć¾ć—ćŸć­ā€¦ć€‚恩恆ćŖć£ć¦ć„ć‚‹ć‚“ć§ć—ć‚‡ć†ļ¼Ÿ

ć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰ć‚’č¦‹ć¦ćæć¾ć™ć€‚

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/share/classes/java/security/SecureRandom.java#L270

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/share/classes/sun/security/provider/SunEntries.java#L337-L340

今ćÆ态/dev/urandomć¾ćŸćÆ/dev/random恌ä½æ恈悌恰NativePRNGćØćŖ悊态恝恆恧ćŖ恑悌恰DRBGćØć„ć†å®Ÿč£…ćæ恟恄恧恙ļ¼ˆļ¼Ÿļ¼‰

ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć§ć©ć†ć«ć‚‚ę±ŗ悁悉悌ćŖć„å “åˆćÆ态SHA1PRNG恌éøꊞ恕悌悋悈恆恧恙怂

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/share/classes/java/security/SecureRandom.java#L284

ć“ć®ć‚ćŸć‚Šć®č©±ćÆ态恓恔悉恫čØ˜č¼‰ćŒć‚ć‚Šć¾ć™ć€‚

ć™ć¹ć¦ć®Java SEå®Ÿč£…ćÆć€å¼•ę•°ćŖć—ć®ć‚³ćƒ³ć‚¹ćƒˆćƒ©ć‚Æć‚ænew SecureRandom()悒ä½æē”Øć—ć¦ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®SecureRandomć‚’ęä¾›ć—ć¾ć™ć€‚ć“ć®ć‚³ćƒ³ć‚¹ćƒˆćƒ©ć‚Æć‚æćÆ态ē™»éŒ²ć•ć‚Œć¦ć„ć‚‹ć‚»ć‚­ćƒ„ćƒŖćƒ†ć‚£ćƒ»ćƒ—ćƒ­ćƒć‚¤ćƒ€ć®ćƒŖć‚¹ćƒˆå†…ć‚’ć€ęœ€ć‚‚ęŽØå„Øć•ć‚Œć‚‹ćƒ—ćƒ­ćƒć‚¤ćƒ€ć‹ć‚‰é †ć«ē¢ŗčŖć—ć€ćć®å¾Œć€SecureRandomä¹±ę•°ć‚øć‚§ćƒćƒ¬ćƒ¼ć‚æ(RNG)ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ć‚’ć‚µćƒćƒ¼ćƒˆć™ć‚‹ęœ€åˆć®ćƒ—ćƒ­ćƒć‚¤ćƒ€ć‹ć‚‰ę–°ć—ć„SecureRandomć‚Ŗ惖ć‚ø悧ć‚Æ惈悒čæ”ć—ć¾ć™ć€‚ć©ć®ćƒ—ćƒ­ćƒć‚¤ćƒ€ć‚‚RNGć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ć‚’ć‚µćƒćƒ¼ćƒˆć—ć¦ć„ćŖć„å “åˆćÆ态SUN惗惭惐悤惀恋悉SHA1PRNG悒ä½æē”Ø恙悋SecureRandomć‚Ŗ惖ć‚ø悧ć‚Æ惈悒čæ”ć—ć¾ć™ć€‚

SecureRandomć‚Ŗ惖ć‚ø悧ć‚Æćƒˆć®ä½œęˆ

恓恓恧态securerandom.sourcećÆć‚³ćƒ”ćƒ³ćƒˆć‚¢ć‚¦ćƒˆć—ćŸć¾ć¾ć€ć‚·ć‚¹ćƒ†ćƒ ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£java.security.egd恧/dev/urandom悒
ęŒ‡å®šć—ć¦ćæć¾ć™ć€‚

$ java -Djava.security.egd=file:/dev/urandom PrintSecureRandomInstanceAlgorithm.java 
SecureRandom Algorithm = NativePRNG

今åŗ¦ćÆ态NativePRNG恫ćŖć‚Šć¾ć—ćŸć­ć€‚

ć¤ć¾ć‚Šć€java.security恮ć‚Øćƒ³ćƒˆćƒ­ćƒ”ćƒ¼åŽé›†ćƒ‡ćƒć‚¤ć‚¹ćØ恄恆恮ćÆ态ꬔ恮2ć¤ć®ć„ćšć‚Œć‹ć§ęŒ‡å®šć™ć‚‹ć‚‚ć®ć®ć‚ˆć†ć§ć™ć€‚

  • ć‚·ć‚¹ćƒ†ćƒ ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£java.security.egd
  • ć‚»ć‚­ćƒ„ćƒŖćƒ†ć‚£ćƒ»ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£ļ¼ˆjava.security.Security#setPropertyć¾ćŸćÆ$JAVA_HOME/conf/security/java.security恮securerandom.sourceļ¼‰

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/share/classes/sun/security/provider/SunEntries.java#L305-L308

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/share/classes/sun/security/provider/SunEntries.java#L325-L333

ć‚»ć‚­ćƒ„ćƒŖćƒ†ć‚£ćƒ»ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£

SecureRandom#getInstanceStrong悒ä½æ恆

ꬔ恫态SecureRandom#getInstanceStrong恧ä½æć‚ć‚Œć‚‹ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ć«ć¤ć„ć¦č¦‹ć¦ć„ćć¾ć—ć‚‡ć†ć€‚

恓恔悉恫恤恄恦ćÆć€ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć«čØ˜č¼‰ćŒć‚ć‚Šć¾ć™ć€‚

java.security.Securityć‚Æćƒ©ć‚¹ć®securerandom.strongAlgorithmsćƒ—ćƒ­ćƒ‘ćƒ†ć‚£ć§å®šē¾©ć•ć‚Œć‚‹å¼·åŠ›ćŖSecureRandomå®Ÿč£…ć‚’å–å¾—ć™ć‚‹ć«ćÆ态getInstanceStrong()ćƒ”ć‚½ćƒƒćƒ‰ć‚’ä½æē”Øć—ć¾ć™ć€‚ć“ć®ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£ćÆć€é‡č¦ćŖå€¤ć‚’ē”Ÿęˆć™ć‚‹ć®ć«é©ć—ćŸćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ å®Ÿč£…ć‚’ćƒŖć‚¹ćƒˆć—ć¾ć™ć€‚

SecureRandomć‚Ŗ惖ć‚ø悧ć‚Æćƒˆć®ä½œęˆ

$JAVA_HOME/conf/security/java.security恮securerandom.strongAlgorithmsćƒ—ćƒ­ćƒ‘ćƒ†ć‚£ć§ęŒ‡å®šć•ć‚Œć¦ć„ć‚‹ć‚ˆć†ć§ć™ć€‚

ē¢ŗčŖć—恦ćæć¾ć—ć‚‡ć†ć€‚

$ grep securerandom.strongAlgorithms /usr/lib/jvm/java-11-openjdk-amd64/conf/security/java.security 
securerandom.strongAlgorithms=NativePRNGBlocking:SUN,DRBG:SUN

ć€Œć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠:ćƒ—ćƒ­ćƒć‚¤ćƒ€ćƒ¼ć€ć®å½¢å¼ć§ę›øć‹ć‚Œć¦ć„ć‚‹ę„Ÿć˜ćŒć—ć¾ć™ć­ć€‚ć¾ćŸć€å·¦ć‹ć‚‰å„Ŗå…ˆć§ć—ć‚‡ć†ć‹ļ¼Ÿ
ćć‚Œć£ć½ć„ę„Ÿć˜ćŒć—ć¾ć™ć€‚

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/share/classes/java/security/SecureRandom.java#L929-L965

試恗恦ćæć¾ć—ć‚‡ć†ć€‚å·¦ē«Æ恫NativePRNG悒čæ½åŠ ć€‚

securerandom.strongAlgorithms=NativePRNG:SUN,NativePRNGBlocking:SUN,DRBG:SUN

ē¢ŗčŖć€‚

$ java PrintSecureRandomInstanceAlgorithm.java strong
SecureRandom Algorithm = NativePRNG

ę­£č§£ć®ć‚ˆć†ć§ć™ć­ć€‚

å·¦ć‚’ć€é–“é•ć£ćŸć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ åć«ć—ć¦ćæć¾ć—ć‚‡ć†ć€‚

securerandom.strongAlgorithms=foo:SUN,bar:SUN,DRBG:SUN

恙悋ćØć€ęœ‰åŠ¹ćŖć‚‚ć®ćŒéøå‡ŗć•ć‚Œć¾ć™ć€‚

$ java PrintSecureRandomInstanceAlgorithm.java strong
SecureRandom Algorithm = DRBG

ćŖ恊态å…ØéƒØå‘ć“ć†ćŖć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠ćØćƒ—ćƒ­ćƒć‚¤ćƒ€ćƒ¼ć®ēµ„ćæåˆć‚ć›ć«ć™ć‚‹ćØć€ä¾‹å¤–ć«ćŖć‚Šć¾ć™ć€‚

Exception in thread "main" java.security.NoSuchAlgorithmException: No strong SecureRandom impls available: xxxxx

SecureRandom#getInstanceStrong悒ä½æć†å “åˆćÆć€ć©ć®ć‚ˆć†ćŖć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠恌éøå‡ŗć•ć‚Œć†ć‚‹ć‹ć€ć”ć‚ƒć‚“ćØē¢ŗčŖć—ć¾ć—ć‚‡ć†ć€
ćØć„ć†ę°—åˆ†ć«ćŖć‚Šć¾ć™ć­ć€‚

file:/dev/urandomćØfile:/dev/random

ć“ć“ć¾ć§ę„ć‚‹ćØ态file:/dev/urandomćØfile:/dev/random恮2ć¤ćŒć‚„ć‚„ę°—ć«ćŖć‚Šć¾ć™ć€‚ć”ć‚‡ć£ćØčŖæć¹ć¦ćæć¾ć—ć‚‡ć†ć€‚

RFC 4086恫悂ę›øć„ć¦ć‚ć‚‹ć€ä¹±ę•°ć‚øć‚§ćƒćƒ¬ćƒ¼ć‚æćƒ¼ć§ć™ć­ć€‚

/dev/random ćÆć€ćć®ćƒ—ćƒ¼ćƒ«ć‹ć‚‰ć®ćƒć‚¤ćƒˆåˆ—ć‚’čæ”ć—ć¾ć™ćŒć€č¦‹ē©ć‚‚ć‚‰ć‚Œć‚‹ć‚Øćƒ³ćƒˆćƒ­ćƒ”ćƒ¼ćŒć‚¼ćƒ­ćØćŖ悋ćØ恍态惖惭惃ć‚Æć—ć¾ć™ć€‚ć‚Øćƒ³ćƒˆćƒ­ćƒ”ćƒ¼ćŒć€ć‚¤ćƒ™ćƒ³ćƒˆć‹ć‚‰ć€ćć®ćƒ—ćƒ¼ćƒ«ć«čæ½åŠ ć•ćˆć‚Œć‚‹ć«å¾“ć£ć¦ć€ć‚ˆć‚Šå¤šćć®ćƒ‡ćƒ¼ć‚æ恌 /dev/random ć‚’é€šć˜ć¦åˆ©ē”ØåÆčƒ½ć«ćŖć‚Šć¾ć™ć€‚ć“ć®ć‚ˆć†ćŖ /dev/random ćƒ‡ćƒć‚¤ć‚¹ć‹ć‚‰å¾—ć‚‰ć‚ŒćŸä¹±é›‘ćŖćƒ‡ćƒ¼ć‚æćÆć€ååˆ†ćŖ乱雑ćŖćƒ“ćƒƒćƒˆåˆ—ćŒćć®ćƒ—ćƒ¼ćƒ«äø­ć«ć‚ć‚‹å “åˆć€ć‚ć‚‹ć„ćÆć€åˆē†ēš„ćŖę™‚é–“ćŒå»¶é•·ć•ć‚Œć¦ć„ć‚‹å “åˆć€é•·ęœŸéµē”Øć®éµē”Ÿęˆć®ćŸć‚ć«é©åˆ‡ć§ć™ć€‚

/dev/urandom ćÆ态/dev/random ć®ć‚ˆć†ć«å‹•ä½œć—ć¾ć™ć€‚ć—ć‹ć—ć€ć“ć‚ŒćÆ态恟ćØćˆä¹±é›‘ę€§ć®ćƒ—ćƒ¼ćƒ«ć«ć¤ć„ć¦ć®ć‚Øćƒ³ćƒˆćƒ­ćƒ”ćƒ¼č¦‹ē©ć‚‚ć‚ŠćŒć‚¼ćƒ­ć«č½ć”悋ćØćć§ć•ćˆć€ćƒ‡ćƒ¼ć‚æć‚’ęä¾›ć—ć¾ć™ć€‚ć“ć‚ŒćÆć€ć‚»ćƒƒć‚·ćƒ§ćƒ³éµē”Ÿęˆē”Ø态恂悋恄ćÆć€ć‚ˆć‚Šå¤šćć®ä¹±é›‘ćŖćƒ“ćƒƒćƒˆåˆ—ć‚’å¾…ć”å—ć‘ć‚‹ć®ć‚’ćƒ–ćƒ­ćƒƒć‚Æ恙悋恓ćØ恌čØ±ć•ć‚ŒćŖ恄悈恆ćŖä»–ć®éµē”Ÿęˆē”Øć«é©åˆ‡ć§ć‚ć‚‹åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚ćŸćØćˆć€ćć®ćƒ—ćƒ¼ćƒ«ć®ć‚Øćƒ³ćƒˆćƒ­ćƒ”ćƒ¼ć®č¦‹ē©ć‚‚ć‚ŠćŒć€ćć®éŽåŽ»ć®å‡ŗåŠ›ć«ćŠć„ć¦å°ć•ć„ćØćć§ć•ćˆć€ćƒ‡ćƒ¼ć‚æ悒ꎔ悊ē¶šć‘悋恓ćØ恮ćƒŖć‚¹ć‚ÆćÆć€ę”»ę’ƒč€…ćŒ SHA-1 悒逆ē®—ć§ćć‚‹ćØ恗恟悉态ē¾åœØ恮å‡ŗåŠ›ć‹ć‚‰č؈ē®—åÆčƒ½ć§ć—ć‚‡ć†ć€‚SHA-1 恌ē¹°ć‚Ščæ”ć•ć‚ŒćŖć„ć‚ˆć†ć«čØ­čØˆć•ć‚Œć¦ć„ć‚‹å “åˆć€ć“ć‚ŒćÆć€åˆē†ēš„ćŖćƒŖć‚¹ć‚Æ恧恙怂

RFC 4086: ć‚»ć‚­ćƒ„ćƒŖćƒ†ć‚£ć®ćƒ©ćƒ³ćƒ€ćƒ ę€§č¦ä»¶ / /dev/random ćƒ‡ćƒć‚¤ć‚¹

/dev/random - Wikipedia

ć–ć£ćć‚ŠčØ€ć†ćØ态/dev/randomćÆ安å…Øę€§ćŒé«˜ć„ć‘ć‚Œć©ćƒ–ćƒ­ćƒƒć‚Æ恙悋åÆčƒ½ę€§ćŒć‚ć‚Šć€/dev/urandomćÆ安å…ØꀧćÆåŠ£ć‚‹ć‚‚ć®ć®
惖惭惃ć‚Æ恗ćŖć„ć®ć§ę€§čƒ½ēš„恫ćÆęœ‰åˆ©ć€ćØ恄恆恓ćØćæ恟恄恧恙怂

ćØ恓悍恧态怌ć‚Øćƒ³ćƒˆćƒ­ćƒ”ćƒ¼ć€ćØćÆļ¼Ÿ

情報量 - Wikipedia

ęŗę³‰ć«ć¤ć„恦ćÆ态RFC 4086恫čØ˜č¼‰ćŒć‚ć‚Šć¾ć™ć€‚

RFC 4086: ć‚»ć‚­ćƒ„ćƒŖćƒ†ć‚£ć®ćƒ©ćƒ³ćƒ€ćƒ ę€§č¦ä»¶ / ć‚Øćƒ³ćƒˆćƒ­ćƒ”ćƒ¼ć®ęŗę³‰

å…ˆć»ć©ć®RFC 4086恮čØ˜č¼‰ć®å†…å®¹ć‹ć‚‰ć„ććØ态OSäøŠć§ć®ć‚­ćƒ¼ćƒœćƒ¼ćƒ‰å…„åŠ›ć€ćƒ‡ć‚£ć‚¹ć‚Æé–¢é€£ć®å‰²ć‚Šč¾¼ćæć€ćƒžć‚¦ć‚¹ć®å‹•ććŖć©ćŒ
ęŗę³‰ćØćŖć‚Šć¾ć™ć€‚ćŸć ć€ć‚µćƒ¼ćƒćƒ¼ć ćØćƒ‡ć‚£ć‚¹ć‚Æé–¢é€£ć®å‰²ć‚Šč¾¼ćæćć‚‰ć„ć—ć‹å…„ę‰‹ć§ććŖ恄恓ćØ恫ćŖć‚Šć¾ć™ćŒć€ćØ怂

RFC 4086: ć‚»ć‚­ćƒ„ćƒŖćƒ†ć‚£ć®ćƒ©ćƒ³ćƒ€ćƒ ę€§č¦ä»¶ / /dev/random ćƒ‡ćƒć‚¤ć‚¹

SecureRandom恮generateSeedćØnextBytes

JDKćƒ—ćƒ­ćƒć‚¤ćƒ€ćƒ»ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’č¦‹ć¦ć„ć‚‹ćØ态NativePRNGćŖć©ć«ćŠć„ć¦ć€ć©ć®ćƒ”ć‚½ćƒƒćƒ‰ć§/dev/random恌ä½æ悏悌悋ćØć„ć£ćŸć“ćØ恌
ę›øć‹ć‚Œć¦ć„ć¾ć™ć€‚

SUN惗惭惐悤惀

具体ēš„恫ćÆ态SecureRandom恮generateSeedćƒ”ć‚½ćƒƒćƒ‰ćØnextBytesćƒ”ć‚½ćƒƒćƒ‰ć§ć™ć€‚

SecureRandom#nextBytesćƒ”ć‚½ćƒƒćƒ‰ćÆć€ćƒ¦ćƒ¼ć‚¶ćƒ¼ćŒęŒ‡å®šć—ćŸćƒć‚¤ćƒˆę•°ć®ä¹±ę•°ćƒć‚¤ćƒˆé…åˆ—ć‚’ē”Ÿęˆć™ć‚‹ć‚‚恮恧恙怂

SecureRandomć‚Ŗ惖ć‚ø悧ć‚Æ惈恮ä½æē”Ø

SecureRandom#generateSeedćƒ”ć‚½ćƒƒćƒ‰ćÆć€ä¹±ę•°ć‚øć‚§ćƒćƒ¬ćƒ¼ć‚æćƒ¼ć«ć‚·ćƒ¼ćƒ‰ć‚’äøŽćˆć‚‹å “åˆć«ä½æē”Øć—ć¾ć™ć€‚

ć‚·ćƒ¼ćƒ‰ćƒ»ćƒć‚¤ćƒˆć®ē”Ÿęˆ

ćØ恓悍恧态SecureRandom#generateSeedćƒ”ć‚½ćƒƒćƒ‰ć‚’ćµć ć‚“ä½æć£ć¦ć„ć‚‹ć‹ćØ恄恆ćØć€å¾®å¦™ćŖćØ恓悍恠ćØę€ć„ć¾ć™ć€‚

SecureRandomć‚Æćƒ©ć‚¹ć®Javadoc悒見悋ćØ态č‡Ŗåˆ†ć§ć‚·ćƒ¼ćƒ‰ć«é–¢ć™ć‚‹ćƒ”ć‚½ćƒƒćƒ‰ć‚’å‘¼ć³å‡ŗ恕ćŖ恄ćØć€ć‚·ćƒ¼ćƒ‰ć•ć‚ŒćŖ恄恓ćØ恌ę›øć‹ć‚Œć¦ć„ć¾ć™ć€‚

SecureRandom (Java SE 11 & JDK 11 )

ć“ć†ć„ć†ęƒ…å ±ć‚’čøć¾ćˆć¦ć€SecureRandomć®å„ćƒ”ć‚½ćƒƒćƒ‰ćØć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ć€ä¹±ę•°ć‚øć‚§ćƒćƒ¬ćƒ¼ć‚æćƒ¼ć®é–¢äæ‚ć‚’č¦‹ć¦ć„ććØč‰Æ恄恮恧恗悇恆恭怂

SecureRandomć®å„ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ć‚’å°‘ć—ēœŗ悁悋

ęœ€å¾Œć«ć€SecureRandomć®å„ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠悒ēœŗ悁恦ćæć¾ć—ć‚‡ć†ć€‚

ć¾ć‚ć€ē°”単ćŖęƒ…å ±ć®ę•“ē†ćØć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰ć®čØ˜č¼‰ć ć‘ć§ć™ćŒć€‚

å„ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠ćÆ态SecureRandomSpić‚Æćƒ©ć‚¹ć®ć‚µćƒ–ć‚Æćƒ©ć‚¹ćØć—ć¦ä½œęˆć•ć‚Œć¦ć„ć¾ć™ć€‚

SecureRandomSpi (Java SE 11 & JDK 11 )

SecureRandomSpić‚Æćƒ©ć‚¹ćÆ态SecureRandomć‚Æćƒ©ć‚¹ćŒå†…éƒØ恧ä½æē”Ø恗恦恄悋悂恮恧恙怂

å„ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ć®å®Ÿč£…ćÆć€ć“ć”ć‚‰ć«ć‚ć‚Šć¾ć™ć€‚

https://github.com/openjdk/jdk11u/tree/jdk-11.0.9+1/src/java.base/share/classes/sun/security/provider

https://github.com/openjdk/jdk11u/tree/jdk-11.0.9%2B1/src/java.base/unix/classes/sun/security/provider

https://github.com/openjdk/jdk11u/tree/jdk-11.0.9+1/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11

https://github.com/openjdk/jdk11u/tree/jdk-11.0.9%2B1/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi

NativePRNG态NativePRNGBlocking态NativePRNGNonBlocking

ęœ€åˆćÆ态NativePRNG态NativePRNGBlocking态NativePRNGNonBlocking恋悉怂

恓悌悉ćÆć€ćƒć‚¤ćƒ†ć‚£ćƒ–OSć‹ć‚‰ä¹±ę•°ć‚’å¾—ć‚‹ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠ćØ恄恆恓ćØ恧恗恟怂

SecureRandomä¹±ę•°ē”Ÿęˆć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠

ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’č¦‹ć‚‹ćØć€ć“ć®ć‚ˆć†ć«ę›øć‹ć‚Œć¦ć„ć¾ć™ć€‚

  • NativePRNG
    • nextBytes ā€¦ /dev/urandom
    • generateSeed ā€¦ /dev/random
  • NativePRNGBlocking
    • nextBytes ā€¦ /dev/random
    • generateSeed ā€¦ /dev/random
  • NativePRNGNonBlocking
    • nextBytes ā€¦ /dev/urandom
    • generateSeed ā€¦ /dev/urandom

SUN惗惭惐悤惀

NativePRNGBlockingćÆnextBytes 态generateSeedć‚’å•ć‚ćšćƒ–ćƒ­ćƒƒć‚Æ恙悋åÆčƒ½ę€§ćŒć‚ć‚‹/dev/random悒ä½æē”Ø恗态
NativePRNGNonBlockingćÆ惖惭惃ć‚Æ恗ćŖ恄/dev/urandom悒ä½æć„ć¾ć™ć€‚

NativePRNGćÆnextBytesćÆ惖惭惃ć‚Æ恗ćŖ恄/dev/urandom悒ä½æ恄态generateSeed恧ćÆ惖惭惃ć‚Æ恙悋åÆčƒ½ę€§ćŒć‚ć‚‹/dev/random悒
ä½æē”Øć—ć¾ć™ć€‚

鍵ćŖ恩恮ē”Ø途恧ä½æć†å “åˆćÆNativePRNGBlocking悒ä½æ恄态恝恆恧ćŖć„å “åˆćÆNativePRNGNonBlocking悒ä½æć†ć®ćŒč‰Æ恕恝恆恧恗悇恆恋怂
nextBytesćƒ”ć‚½ćƒƒćƒ‰ć®ćæ悒ä½æć†å “åˆćÆ态NativePRNGćØNativePRNGNonBlockingć«å·®ćÆćŖ恕恝恆恧恙恭怂

恓恮3恤ćÆć€åŒć˜ć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰äø­ć«åŽć‚ć‚‰ć‚Œć¦ć„ć¾ć™ć€‚

NativePRNG怂

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/unix/classes/sun/security/provider/NativePRNG.java

NativePRNGBlocking怂

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/unix/classes/sun/security/provider/NativePRNG.java#L241

NativePRNGNonBlocking怂

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/unix/classes/sun/security/provider/NativePRNG.java#L290

å®Ÿéš›ć«ć€å„ä¹±ę•°ć‚øć‚§ćƒćƒ¬ćƒ¼ć‚æćƒ¼ļ¼ˆ/dev/randomćŖ恩ļ¼‰ć‚’ć©ć†å‰²ć‚Šå½“ć¦ć¦ć„ć‚‹ć‹ćÆć€ć“ć”ć‚‰ć‚’č¦‹ć‚Œć°ć‚ˆć„ć§ć—ć‚‡ć†ć€‚

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/unix/classes/sun/security/provider/NativePRNG.java#L137-L173

ćŖ恊态NativePRNG恮generateSeed恫恤恄恦ćÆć‚Øćƒ³ćƒˆćƒ­ćƒ”ćƒ¼åŽé›†ćƒ‡ćƒć‚¤ć‚¹ć®ęŒ‡å®šć§čŖæę•“åÆčƒ½ćŖ悈恆恧恙怂

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/unix/classes/sun/security/provider/NativePRNG.java#L139-L152

SHA1PRNG

SHA1PRNG恮čŖ¬ę˜ŽćÆ恓恆恧恗恟怂

Sunćƒ—ćƒ­ćƒć‚¤ćƒ€ćŒęä¾›ć™ć‚‹ę“¬ä¼¼ä¹±ę•°ē”Ÿęˆ(PRNG)ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠怂 ć“ć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠ćÆ态PRNG恮åŸŗē›¤ćØ恗恦SHA-1悒ä½æē”Øć—ć¾ć™ć€‚ å„ę“ä½œć«ć¤ćå€¤ćŒ1å¢—åŠ ć™ć‚‹64ćƒ“ćƒƒćƒˆćƒ»ć‚«ć‚¦ćƒ³ć‚æ悒ä½æć£ć¦éŽ–ēŠ¶ć«ć¤ćŖćŒć£ćŸēœŸć«ćƒ©ćƒ³ćƒ€ćƒ ćŖć‚·ćƒ¼ćƒ‰å€¤ć‹ć‚‰ć€SHA-1ćƒćƒƒć‚·ćƒ„ć‚’č؈ē®—ć—ć¾ć™ć€‚ 160ćƒ“ćƒƒćƒˆć®SHA-1å‡ŗåŠ›ć®ć†ć”ć€64惓惃惈恠恑恌ä½æē”Øć•ć‚Œć¾ć™ć€‚

SecureRandomä¹±ę•°ē”Ÿęˆć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠

ć©ć®ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ć§ć‚‚ä½æ恈悋恓ćØ恌ē‰¹å¾“恧恙怂

å®Ÿč£…ćØ恗恦ćÆć€ć“ć”ć‚‰ć®ć‚ˆć†ć§ć™ć€‚

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/share/classes/sun/security/provider/SecureRandom.java

ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠悒ē™»éŒ²ć—恦恄悋ćØ恓悍怂

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/share/classes/sun/security/provider/SunEntries.java#L123-L124

恔ćŖćæ恫态SHA1PRNGćÆęš—å·å­¦ēš„ć«å®‰å…Ø恧ćÆćŖ恄恟悁态éæć‘ćŸę–¹ćŒć‚ˆć•ćć†ć§ć™ć­ć€‚

Google Developers Japan: Android N で廃止されるセキュリティ「Crypto」プロバイダ

NativePRNGē³»ć®ć‚‚ć®ćŒä½æ恈ćŖ恄Windows恠ćØ态DRBG悒ä½æć£ćŸę–¹ćŒč‰Æ恄恮恧ćÆļ¼Ÿ

DRBG

DRBGćÆ态Java 9恋悉čæ½åŠ ć•ć‚ŒćŸć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠恧恙怂

JEP 273: DRBG-Based SecureRandom Implementations

ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć«ć‚ˆć‚‹ćØć“ć®ć‚ˆć†ćŖčŖ¬ę˜Žć«ćŖć£ć¦ć„ć¾ć™ć€‚

NIST SP 800-90Ar1ć§å®šē¾©ć•ć‚Œć¦ć„ć‚‹DRBGćƒ”ć‚«ćƒ‹ć‚ŗ惠悒ä½æē”Ø恗恦SUNćƒ—ćƒ­ćƒć‚¤ćƒ€ć‹ć‚‰ęä¾›ć•ć‚ŒćŸć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠

SecureRandomä¹±ę•°ē”Ÿęˆć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠

NIST Special Publication 800-90A / Recommendation for Random Number Generation Using Deterministic Random Bit Generators

ć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰ćÆ恓恔悉怂

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/share/classes/sun/security/provider/DRBG.java

ć¾ćŸć€ćƒ—ćƒ­ćƒć‚¤ćƒ€ćƒ¼ć®čŖ¬ę˜Žć«ćÆ态仄äø‹ć®ć‚ˆć†ć«ę›øć‹ć‚Œć¦ć„ć¾ć™ć€‚

ę¬”ć®ćƒ”ć‚«ćƒ‹ć‚ŗ惠ćØć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ćŒć‚µćƒćƒ¼ćƒˆć•ć‚Œć¦ć„ć¾ć™ć€‚SHA-224态SHA-512/224态SHA-256态SHA-512/256态SHA-384ćŠć‚ˆć³SHA-512悒ä½æē”Ø恙悋Hash_DRBGćŠć‚ˆć³HMAC_DRBG怂AES-128态AES-192ćŠć‚ˆć³AES-256悒ä½æē”Ø恙悋CTR_DRBG (導å‡ŗé–¢ę•°ć‚’ä½æē”Øć™ć‚‹å “åˆćØä½æē”Ø恗ćŖć„å “åˆćŒć‚ć‚‹)ć€‚å„ēµ„åˆć›ć§ć‚µćƒćƒ¼ćƒˆć•ć‚Œć¦ć„ć‚‹äŗˆęø¬č€ę€§ćØå†ć‚·ćƒ¼ćƒ‰ć€ćŠć‚ˆć³ć‚»ć‚­ćƒ„ćƒŖćƒ†ć‚£å¼·åŗ¦ćÆ态112ć‹ć‚‰ć€ćć‚ŒćŒć‚µćƒćƒ¼ćƒˆć™ć‚‹ęœ€å¤§å¼·åŗ¦ć¾ć§č¦ę±‚ć§ćć¾ć™ć€‚

SUN惗惭惐悤惀

恓恮čŖ¬ę˜Žć‹ć‚‰ć—ć¦ć€å˜ć«ć€ŒDRBG怍ćØęŒ‡å®šć™ć‚‹ä»„å¤–ć«ć‚‚čŖæę•“åÆčƒ½ćŖ項ē›®ćŒć‚ć‚Šćć†ć§ć™ć­ć€‚
ć“ć®ć‚ćŸć‚Šć®č¦ä»¶ć«åˆć‚ć›ć¦čŖæę•“åÆčƒ½ćŖ恓ćØ恌态DRBGć®ćƒć‚¤ćƒ³ćƒˆć®ć‚ˆć†ć§ć™ć€‚

恓恔悉恫态securerandom.drbg.configćØć„ć†ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£ć®čŖ¬ę˜ŽćŒć‚ć‚Šć¾ć™ć€‚

securerandom.drbg.configćÆ态java.security.Securityć‚Æćƒ©ć‚¹ć®ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£ć§ć™ć€‚

SecureRandomć‚Æćƒ©ć‚¹

ćØ恄恆悏恑恧态$JAVA_HOME/conf/security/java.securityćƒ•ć‚”ć‚¤ćƒ«ć‚’ē¢ŗčŖć—恦ćæć¾ć™ć€‚

securerandom.drbg.config=

項ē›®ćØ恗恦ćÆ存åœØć—ć¾ć™ćŒć€å€¤ćŒē©ŗ恧恙恭怂

ćć®äøŠć®ć‚³ćƒ”ćƒ³ćƒˆć‚’č¦‹ć‚‹ćØ态čØ­å®šę–¹ę³•ćŒę›øć‹ć‚Œć¦ć„ć¾ć™ć€‚

# Examples,
#   securerandom.drbg.config=Hash_DRBG,SHA-224,112,none
#   securerandom.drbg.config=CTR_DRBG,AES-256,192,pr_and_reseed,use_df
#
# The default value is an empty string, which is equivalent to
#   securerandom.drbg.config=Hash_DRBG,SHA-256,128,none
#

ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®å€¤ćÆ态恓恔悉恧恙态ćØ怂

securerandom.drbg.config=Hash_DRBG,SHA-256,128,none

ćƒ”ć‚«ćƒ‹ć‚ŗ惠ļ¼ˆHash_DRBG态CTR_DRBG态Hmac_DRBGļ¼‰ć€ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠ļ¼ˆSHA-256ćŖ恩ļ¼‰ć€å¼·åŗ¦ļ¼ˆ112怜ļ¼‰ćŖć©ćŒęŒ‡å®šć§ćć¾ć™ć€‚

꧋ꖇ怂

#   aspect:
#     mech_name | algorithm_name | strength | capability | df

ćƒ”ć‚«ćƒ‹ć‚ŗ惠怂

#   // The DRBG mechanism to use. Default "Hash_DRBG"
#   mech_name:
#     "Hash_DRBG" | "HMAC_DRBG" | "CTR_DRBG"

ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠怂

#   // The DRBG algorithm name. The "SHA-***" names are for Hash_DRBG and
#   // HMAC_DRBG, default "SHA-256". The "AES-***" names are for CTR_DRBG,
#   // default "AES-128" when using the limited cryptographic or "AES-256"
#   // when using the unlimited.
#   algorithm_name:
#     "SHA-224" | "SHA-512/224" | "SHA-256" |
#     "SHA-512/256" | "SHA-384" | "SHA-512" |
#     "AES-128" | "AES-192" | "AES-256"

å¼·åŗ¦ć€‚

#   // Security strength requested. Default "128"
#   strength:
#     "112" | "128" | "192" | "256"

äŗˆęø¬č€ę€§ćØå†ć‚·ćƒ¼ćƒ‰ć€‚

#   // Prediction resistance and reseeding request. Default "none"
#   //  "pr_and_reseed" - Both prediction resistance and reseeding
#   //                    support requested
#   //  "reseed_only"   - Only reseeding support requested
#   //  "none"          - Neither prediction resistance not reseeding
#   //                    support requested
#   pr:
#     "pr_and_reseed" | "reseed_only" | "none"

ćƒ”ć‚«ćƒ‹ć‚ŗ惠恌CTR_DRBGć®ę™‚ć«ć€å°Žå‡ŗé–¢ę•°ć‚’ä½æē”Ø恙悋恋恩恆恋怂

#   // Whether a derivation function should be used. only applicable
#   // to CTR_DRBG. Default "use_df"
#   df:
#     "use_df" | "no_df"

ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£ć«ęŒ‡å®šć—ćŸé …ē›®ć‚’ćƒ‘ćƒ¼ć‚¹ć—ć¦ć„ć‚‹ć®ćÆć€ć“ć®ć‚ćŸć‚Šć§ć™ć­ć€‚

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/share/classes/sun/security/provider/DRBG.java#L98-L149

Linuxē’°å¢ƒäø‹ć§ćÆ态SecureRandom#getInstanceStrongć®ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆčØ­å®šćŒć“ć†ć ć£ćŸć“ćØ悂恂悊态NativePRNGē³»ć®ć‚‚ć®ćŒ
ä½æ恈悋ēŠ¶ę…‹ć§ć‚ć‚Œć°ć€ćć”悉恧悂恄恄恋ćŖļ¼Ÿ

securerandom.strongAlgorithms=NativePRNGBlocking:SUN,DRBG:SUN
PKCS11

PKCS11ćƒ©ć‚¤ćƒ–ćƒ©ćƒŖć‚ˆć‚Šć€ä¹±ę•°ć‚’å–å¾—ć™ć‚‹ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠恧恙怂

SunPKCS11惗惭惐悤惀

ć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰ćÆ恓恔悉怂

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecureRandom.java

ć‚ć‚“ć¾ć‚Šę·±čæ½ć„ć—ć¾ć›ć‚“ā€¦ć€‚

Windows-PRNG

Windows OSć‹ć‚‰ä¹±ę•°ć‚’å–å¾—ć™ć‚‹ć‚¢ćƒ«ć‚“ćƒŖć‚ŗ惠态ćØćŖć£ć¦ć„ć¾ć™ćŒā€¦Windows-PRNGćØ恄恆悂恮ćÆćŖćć€å®Ÿä½“ćÆSunMSCAPI
ć ć£ćŸć‚Šć—ć¾ć™ć€‚

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/PRNG.java

Windowsē”Ø恮NativePRNG恮ć‚Æćƒ©ć‚¹ćÆć‚ć‚Šć¾ć™ćŒć€å®Ÿä½“ćŒć‚ć‚Šć¾ć›ć‚“ć€‚

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9%2B1/src/java.base/unix/classes/sun/security/provider/NativePRNG.java

ć“ć”ć‚‰ć‚‚ć€ć‚ć‚“ć¾ć‚Šę·±čæ½ć„ć—ć¾ć›ć‚“ā€¦ć€‚

ć¾ćØ悁

ć“ć‚Œć¾ć§ć‚ć¾ć‚Šč¦‹ć¦ć“ćŖć‹ć£ćŸć€SecureRandomć®ć‚¢ćƒ«ć‚“ćƒŖć‚ŗćƒ ć«ć¤ć„ć¦ć€ć”ć‚‡ć£ćØčæ½ć£ć¦ćæć¾ć—ćŸć€‚

ē”ØčŖžćŖ恩ćØć”ć‚ƒć‚“ćØå‘ćåˆć£ć¦ć„ćŖć‹ć£ćŸć®ć§ć€ć‹ćŖć‚Šč‹¦åŠ“ć—ć¾ć—ćŸćŒā€¦ć„ć‚ć„ć‚å‹‰å¼·ć«ćŖć‚Šć¾ć—ćŸć­ć‡ć€‚

今åŗ¦ć‹ć‚‰ć€ć—ć£ć‹ć‚Šč¦‹ć‚‹ć‚ˆć†ć«ć—ć¾ć—ć‚‡ć†ā€¦ć€‚

å‚č€ƒ

JCA (Java 暗号化アーキテクチャ)使い方メモ - Qiita

#JJUG Java における乱数生成器とのつき合い方 - Speaker Deck

Java における乱数生成器とのつき合い方 / #JJUG CCC 2019 fall に登壇してきました - k11i.biz

[java] SecureRandom のアルゴリズムの選択について - tokuhirom's blog