感謝大家的意見。我不得不解釋這個問題。爲什麼使用相同的字符串,密鑰和SecureRandom加密Java密碼總是不一樣?
我知道我們不應該比較使用固定隨機發生器加密的結果,因爲它可能會降低安全性。但是,我只是想在測試中做到這一點,我會使用原始機制的隨機在實際運行。
的情況是,我需要通過以下步驟登錄使用帳號/密碼的服務器:
- 從服務器獲取信息:a.b.com/get_cipher.cgi。
- 接收到響應,解析它並獲取一些信息來創建密碼。
- 使用密碼來加密帳戶/密碼,然後撰寫以下URL ABCOM/login.cgi?加密= {encrypted_account_password}
這是一個複雜的過程,我無法請求服務器來改變protocal。我想測試整個登錄過程。因此,我試圖提供假帳戶/密碼,並檢查生成的url是否正確,而不解密結果(如果解密結果,這意味着,在這個測試案例中,我需要解密加密結果,解析url,並提取相關信息,太多與測試無關,而且,如果我在登錄過程中做了一些改動,我可能需要修改測試用例中的解密和解析過程。)
散列函數不適合我。 (原來的登錄過程不使用任何散列,因此我不想在測試用例中進行測試。而且,即使我認爲檢查散列結果是正確的,但它並不證明登錄過程是正確的。)
===原來的問題是,如下===
我有一個程序,它需要登錄。要在網絡上以純文本形式傳輸密碼,我需要對其進行加密。換句話說,登錄過程包含一個加密階段。
然後,我想爲整個登錄過程編寫一個測試用例。如果使用相同的帳戶和密碼,我認爲加密結果是相同的。
因爲它可以在加密過程中使用的SecureRandom,我寫了一個假的SecureRandom通過的Mockito如下面的代碼:
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<Object>() {
@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.<byte[]>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 < 20; i++) {
isTheSameSeries &= (bytes1[i]==bytes2[i]);
}
assertThat(isTheSameSeries, is(true));
}
的generateRandomWithFixSeed()將新的隨機使用相同的密鑰,從而使它會產生相同的結果。這個generateSecureRandomWithFixSeed()使用Makito檢測函數調用nextBytes()並始終回答隨機結果。測試test_SecureRandom_WithFixSeed()也顯示兩個不同的SecureRandom實例生成相同的結果。
但是,如果我在密碼中使用generateSecureRandomWithFixSeed(),如下所示,它不總是返回相同的結果。
@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));
}
AA
只是一對夫婦的想法...你可能會嘗試調用cipher.getIV()來查看是否有一個初始化向量不同。您可能還想通過將加密字節與常量進行比較來測試,但使用DECRYPT_MODE將從加密字節解密的值與原始值進行比較。 –