title: Why the encryption of Java Cipher with the same string, key and SecureRandom always differ?
body: <p>Thanks the comments from everyone.</p>
  
  <p>However, I have to explain this question.</p>
  
  <p>I know that we <strong>shouldn't</strong> compare the result of encryption by using a fix random generator due to it may reduce the secure.  However, I just want to do it in <strong>testing</strong> and I'll use a <strong>original mechanism of random</strong> in <strong>real running</strong>.</p>
  
  <p>The case is that I need to login a server with account/password by the following steps:</p>
  
  <ol>
  <li>Get info from server: a.b.com/get_cipher.cgi.</li>
  <li>receive the response, parse it and get some info to create a cipher.</li>
  <li>use the cipher to encrypt account/password and then compose the following URL a.b.com/login.cgi?encrypted={encrypted_account_password}</li>
  </ol>
  
  <p>It's a complex process and I can't request the server to change the protocal. I want to test <strong>the whole login process</strong>. Thus, I tried to provide fake account/password and check if the generated url is correct without deciphering the result (if deciphering the result, it means that, in this test case, I need to decipher the the encrypted result, parse the url, and extract the related info, there are too much not related to the testing. Moreover, if I do some change in the login process, I may need to modify the deciphering and parsing process in the test cases.)</p>
  
  <p>That means a hash function is not proper for me. (The original login process don't use any hash so that I don't want to test it in a test cases.  Moreover, even thought I check the hash result is correct, it doesn't prove the <strong>login process</strong> is correct.)</p>
  
  <p><strong>=== The original question is as the following ===</strong></p>
  
  <p>I have a program which needs login. To void transfer the password in plain text on the network, I need to encipher it. In other word, the login process contains a ciphering phase.</p>
  
  <p>Then, I want to write a test case for the whole login process. I think the encryption result of be the same if it use the same account and password.</p>
  
  <p>Since it may use SecureRandom in the encryption process, I write a fake SecureRandom by Mockito as the following code:</p>
  
  <pre><code>private static final long RANDOM_SEED = 3670875202692512518L;
  private Random generateRandomWithFixSeed() {
      Random random = new Random(RANDOM_SEED);
      return random;
  }
  
  private SecureRandom generateSecureRandomWithFixSeed() {
      final Random random = generateRandomWithFixSeed();
      final SecureRandom secureRandom = new SecureRandom();
      final SecureRandom spySecureRandom = Mockito.spy(secureRandom);
  
      Mockito.doAnswer(new Answer&lt;Object&gt;() {
          @Override
          public Object answer(InvocationOnMock invocation) throws Throwable {
              Object[] args = invocation.getArguments();
              byte[] bytes = (byte[]) args[0];
              random.nextBytes(bytes);
              return bytes;
          }
      })
              .when(spySecureRandom)
              .nextBytes(Matchers.&lt;byte[]&gt;anyObject());
  
      return spySecureRandom;
  }
  
  @Test
  public void test_SecureRandom_WithFixSeed() {
      final SecureRandom secureRandom1 = generateSecureRandomWithFixSeed();
      final SecureRandom secureRandom2 = generateSecureRandomWithFixSeed();
  
      final byte[] bytes1 = new byte[20];
      final byte[] bytes2 = new byte[20];
  
      secureRandom1.nextBytes(bytes1);
      secureRandom2.nextBytes(bytes2);
  
      boolean isTheSameSeries = true;
      for(int i = 0; i &lt; 20; i++) {
          isTheSameSeries &amp;= (bytes1[i]==bytes2[i]);
      }
  
      assertThat(isTheSameSeries, is(true));
  }
  </code></pre>
  
  <p>The <strong>generateRandomWithFixSeed()</strong> will new a Random with the same key, so that it will generate the same result. The <strong>generateSecureRandomWithFixSeed()</strong> uses Makito to detect the function call nextBytes() and always answer the result of the random. the test <strong>test_SecureRandom_WithFixSeed()</strong> also show two different SecureRandom instances generate the same results.</p>
  
  <p>However, if I use generateSecureRandomWithFixSeed() in the cipher as the following, it can't always return the same result.</p>
  
  <pre><code>    @Test
  public void test_cipher() {
      final SecureRandom secureRandomWithFixSeed = generateSecureRandomWithFixSeed();
  
      final String pkcs = "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAv7n+/uWHHVC7229QLEObeH0vUcOagavDukf/gkveqgZsszzGkZQaXfsrjdPiCnvjozCy1tbnLu5EInDy4w8B+a9gtK8KqsvlsfuaT9kRSMUS8CfgpWj8JcJwijmeZhjR52k0UBpWLfn3JmRYW8xjZW6dlOSnS0yqwREPU7myyqUzhk1vyyUG7wLpk7uK9Bxmup0tnbnD4MeqDboAXlQYnIFVV+CXywlAQfHHCfQRsGhsEtu4excZVw7FD1rjnro9bcWFY9cm/KdDBxZCYQoT/UW0OBbipoINycrmfMKt1r4mGE9/MdVoIEMBc54aI6sb2g5J2GtNCYfEu+1/gA99xY0+5B3ydH74cbqfHYOZIvu11Q7GnpZ6l8zTLlMuF/pvlSily76I45H0YZ3HcdQnf/GoKC942P6fNsynHEX01zASYM8dzyMxHQpNEx7fcXGi+uiBUD/Xdm2jwzr9ZEP5eEVlrpcAvr8c9S5ylE50lwR+Mp3vaZxPoLdSGZrfyXy4v97UZSnYARQBacmn6KgsIHIOKhYOxNgUG0jwCO/zrPvlbjiYTHQYLOCcldTULvXOdn51enJFGVjscGoZfRj6vZgyHVCUW4iip4iSbSKPcPbf0GMZuniS9qJ3Wybve0/xpppdOv1c40ez0NKQyQkEZRb+V0qfesatJKZd/hUGr+MCAwEAAQ==";
      final byte bytePKCS[] = Base64.base64ToByteArray(pkcs);
      final X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(bytePKCS);
  
      PublicKey pubKey = null;
      try {
          pubKey = KeyFactory.getInstance("RSA").generatePublic(pubKeySpec);
      } catch (InvalidKeySpecException e) {
          e.printStackTrace();
      } catch (NoSuchAlgorithmException e) {
          e.printStackTrace();
      }
  
      final String targetResultText = "NZqTzuNli92vuXEQNchGeF6faN/NBHykhfqBFcWzBHZhbgljZaWAcAzasFSm/odZZ6vBD2jK7J4oi5BmDjxNdEjkXyv3OZ2sOTLCfudgPwXcXmmhOwWHDLY02OX0X3RwBHzqWczqAd4dwslo59Gp5CT59GWXenJPL8wvG90WH2XAKOmHg5uEZj55ZvErRQ6StPVzLkiNCMPOhga7FZWK/rSEpT6BHDy3CibDZ0PNRtAW4wiYAr0Cw6brqiqkN301Bz6DzrV5380KDHkw26GjM8URSTFekwvZ7FISQ72UaNHhjnh1WgMIPf/QDbrEh5b+rmdZjzc5bdjyONrQuoj0rzrWLN4z8lsrBnKFVo+zVyUeqr0IxqD2aHDLyz5OE4fb5IZJHEMfYr/R79Zfe8IuQ2tusA02ZlFzGRGBhAkb0VygXxJxPXkjbkPaLbZQZOsKLUoIDkcbNoUTxeS9+4LWVg1j5q3HR9OSvmsF5I/SszvVrnXdNaz1IKCfVYkwpIBQ+Y+xI/K360dWIHR/vn7TU4UsGmWtwVciq0jWLuBN/qRE6MV47TDRQu63GzeV00yAM/xUM33qWNXCV1tbGXNZw8jHpakgflTY0hcjOFHPpq2UfJCyxiSBtZ0b7hw9Rvhi8VwYc243jXO9CvGq+J6JYvchvKHjq2+YKn1UB2+gs20=";
      final String plainText = "a";
      String resultText = "";
      try {
          Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
          cipher.init(Cipher.ENCRYPT_MODE, pubKey, secureRandomWithFixSeed);
          final byte[] result = cipher.doFinal(plainText.getBytes());
          resultText = Base64.byteArrayToBase64(result);
      } catch (NoSuchAlgorithmException e) {
          e.printStackTrace();
      } catch (NoSuchPaddingException e) {
          e.printStackTrace();
      } catch (IllegalBlockSizeException e) {
          e.printStackTrace();
      } catch (BadPaddingException e) {
          e.printStackTrace();
      } catch (InvalidKeyException e) {
          e.printStackTrace();
      }
      assertThat(resultText, is(targetResultText));
  }
  </code></pre>
  
  <p>aa</p>