< prev index next >

test/java/security/SecureRandom/Serialize.java

Print this page
rev 13987 : 8051408: NIST SP 800-90A SecureRandom implementations

@@ -29,18 +29,70 @@
 import java.security.*;
 import java.io.*;
 
 public class Serialize {
 
-    public static void main(String args[]) throws IOException {
+    public static void main(String args[]) throws Exception {
+        for (String alg: new String[]{
+                "SHA1PRNG", "DRBG", "Hash_DRBG", "HMAC_DRBG", "CTR_DRBG"}) {
+            System.out.println("Testing " + alg);
 
-        FileOutputStream fos = new FileOutputStream("t.tmp");
-        ObjectOutputStream oos = new ObjectOutputStream(fos);
+            // Even unseeded object can be serialized and deserialized
+            SecureRandom s1 = getInstance(alg);
+            revive(s1).nextInt();
+            if (alg.contains("DRBG")) {
+                revive(s1).reseed();
+            }
+
+            // After seeded, deserialized object should emit same random data
+            s1 = getInstance(alg);
+            s1.nextInt();    // state set
+            SecureRandom s2 = revive(s1);
+            int n1 = s1.nextInt();
+            int n2 = s2.nextInt();
+            if (n1 != n2) {
+                throw new Exception();
+            }
 
-        SecureRandom secRandom = new SecureRandom();
+            // Or seeded with user-provided data
+            s1.setSeed(42);
+            s2.setSeed(42);
+            n1 = s1.nextInt();
+            n2 = s2.nextInt();
+            if (n1 != n2) {
+                throw new Exception();
+            }
+
+            // But not after automatic reseed
+            if (alg.contains("DRBG")) {
+                s1.reseed();
+                s2.reseed();
+                n1 = s1.nextInt();
+                n2 = s2.nextInt();
+                if (n1 == n2) {
+                    throw new Exception();
+                }
+            }
+        }
+    }
+
+    private static SecureRandom getInstance(String alg) throws Exception {
+        if (alg.equals("SHA1PRNG") || alg.equals("DRBG")) {
+            return SecureRandom.getInstance(alg);
+        } else {
+            String old = Security.getProperty("drbg");
+            try {
+                Security.setProperty("drbg", alg);
+                return SecureRandom.getInstance("DRBG");
+            } finally {
+                Security.setProperty("drbg", old);
+            }
+        }
+    }
 
-        // serialize and write out
-        oos.writeObject(secRandom);
-        oos.flush();
-        oos.close();
+    private static SecureRandom revive(SecureRandom sr) throws Exception {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        new ObjectOutputStream(bout).writeObject(sr);
+        return (SecureRandom) new ObjectInputStream(
+                new ByteArrayInputStream(bout.toByteArray())).readObject();
     }
 }
< prev index next >