diff --git a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/AbstractPrivateKeyObfuscator.java b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/AbstractPrivateKeyObfuscator.java index 45f694272..5f3ac93e1 100644 --- a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/AbstractPrivateKeyObfuscator.java +++ b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/AbstractPrivateKeyObfuscator.java @@ -23,7 +23,6 @@ import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.security.MessageDigest; -import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.util.Arrays; import java.util.Objects; @@ -34,6 +33,7 @@ import javax.crypto.spec.SecretKeySpec; import org.apache.sshd.common.digest.BuiltinDigests; +import org.apache.sshd.common.random.JceRandom; import org.apache.sshd.common.util.GenericUtils; import org.apache.sshd.common.util.ValidateUtils; import org.apache.sshd.common.util.buffer.BufferUtils; @@ -59,7 +59,7 @@ public byte[] generateInitializationVector(PrivateKeyEncryptionContext encContex throws GeneralSecurityException { int ivSize = resolveInitializationVectorLength(encContext); byte[] initVector = new byte[ivSize]; - Random randomizer = new SecureRandom(); // TODO consider using some pre-created singleton instance + Random randomizer = JceRandom.getGlobalInstance(); randomizer.nextBytes(initVector); return initVector; } diff --git a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/writer/openssh/OpenSSHKeyPairResourceWriter.java b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/writer/openssh/OpenSSHKeyPairResourceWriter.java index 8a9653add..9df264183 100644 --- a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/writer/openssh/OpenSSHKeyPairResourceWriter.java +++ b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/writer/openssh/OpenSSHKeyPairResourceWriter.java @@ -30,7 +30,6 @@ import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; -import java.security.SecureRandom; import java.util.Arrays; import java.util.Base64; import java.util.Objects; @@ -51,6 +50,7 @@ import org.apache.sshd.common.config.keys.loader.openssh.kdf.BCrypt; import org.apache.sshd.common.config.keys.loader.openssh.kdf.BCryptKdfOptions; import org.apache.sshd.common.config.keys.writer.KeyPairResourceWriter; +import org.apache.sshd.common.random.JceRandom; import org.apache.sshd.common.random.JceRandomFactory; import org.apache.sshd.common.random.Random; import org.apache.sshd.common.util.GenericUtils; @@ -148,7 +148,7 @@ public static OpenSSHKeyEncryptionContext determineEncryption(OpenSSHKeyEncrypti public static byte[] encodePrivateKey(KeyPair key, String keyType, int blockSize, String comment) throws IOException, GeneralSecurityException { try (SecureByteArrayOutputStream out = new SecureByteArrayOutputStream()) { - int check = new SecureRandom().nextInt(); + int check = JceRandom.getGlobalInstance().nextInt(); KeyEntryResolver.encodeInt(out, check); KeyEntryResolver.encodeInt(out, check); KeyEntryResolver.encodeString(out, keyType); diff --git a/sshd-common/src/main/java/org/apache/sshd/common/random/JceRandom.java b/sshd-common/src/main/java/org/apache/sshd/common/random/JceRandom.java index 4ef8c1f1f..f360b854e 100644 --- a/sshd-common/src/main/java/org/apache/sshd/common/random/JceRandom.java +++ b/sshd-common/src/main/java/org/apache/sshd/common/random/JceRandom.java @@ -51,6 +51,20 @@ private static SecureRandom getRandom() { } } + private static final class Cache { + + static final SecureRandom INSTANCE = getRandom(); + + private Cache() { + // No instantiation + super(); + } + } + + public static SecureRandom getGlobalInstance() { + return Cache.INSTANCE; + } + @Override public String getName() { return NAME; diff --git a/sshd-core/src/main/java/org/apache/sshd/certificate/OpenSshCertificateBuilder.java b/sshd-core/src/main/java/org/apache/sshd/certificate/OpenSshCertificateBuilder.java index da721c682..e8e6597e3 100644 --- a/sshd-core/src/main/java/org/apache/sshd/certificate/OpenSshCertificateBuilder.java +++ b/sshd-core/src/main/java/org/apache/sshd/certificate/OpenSshCertificateBuilder.java @@ -40,6 +40,7 @@ import org.apache.sshd.common.config.keys.OpenSshCertificate.Type; import org.apache.sshd.common.config.keys.OpenSshCertificateImpl; import org.apache.sshd.common.keyprovider.KeyPairProvider; +import org.apache.sshd.common.random.JceRandom; import org.apache.sshd.common.signature.BuiltinSignatures; import org.apache.sshd.common.signature.Signature; import org.apache.sshd.common.signature.SignatureFactory; @@ -241,7 +242,7 @@ public OpenSshCertificate sign(KeyPair caKeypair, String signatureAlgorithm) thr if (nonce != null) { cert.setNonce(nonce); } else { - SecureRandom rand = new SecureRandom(); + SecureRandom rand = JceRandom.getGlobalInstance(); byte[] tempNonce = new byte[32]; rand.nextBytes(tempNonce); cert.setNonce(tempNonce); diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/SNTRUP761.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/SNTRUP761.java index d423d882b..66ef88423 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/kex/SNTRUP761.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/SNTRUP761.java @@ -18,9 +18,9 @@ */ package org.apache.sshd.common.kex; -import java.security.SecureRandom; import java.util.Arrays; +import org.apache.sshd.common.random.JceRandom; import org.apache.sshd.common.util.security.SecurityUtils; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.SecretWithEncapsulation; @@ -64,7 +64,7 @@ static class Client implements KeyEncapsulationMethod.Client { @Override public void init() { SNTRUPrimeKeyPairGenerator gen = new SNTRUPrimeKeyPairGenerator(); - gen.init(new SNTRUPrimeKeyGenerationParameters(new SecureRandom(), SNTRUPrimeParameters.sntrup761)); + gen.init(new SNTRUPrimeKeyGenerationParameters(JceRandom.getGlobalInstance(), SNTRUPrimeParameters.sntrup761)); AsymmetricCipherKeyPair pair = gen.generateKeyPair(); extractor = new SNTRUPrimeKEMExtractor((SNTRUPrimePrivateKeyParameters) pair.getPrivate()); publicKey = (SNTRUPrimePublicKeyParameters) pair.getPublic(); @@ -104,7 +104,7 @@ public byte[] init(byte[] publicKey) { throw new IllegalArgumentException("KEM public key too short: " + publicKey.length); } byte[] pk = Arrays.copyOf(publicKey, pkBytes); - SNTRUPrimeKEMGenerator kemGenerator = new SNTRUPrimeKEMGenerator(new SecureRandom()); + SNTRUPrimeKEMGenerator kemGenerator = new SNTRUPrimeKEMGenerator(JceRandom.getGlobalInstance()); SNTRUPrimePublicKeyParameters params = new SNTRUPrimePublicKeyParameters(SNTRUPrimeParameters.sntrup761, pk); value = kemGenerator.generateEncapsulated(params); return Arrays.copyOfRange(publicKey, pkBytes, publicKey.length);