/** * Test with random plain text strings and random passwords. UUIDs are used and hence will only * cover hex characters (and the separator hyphen). * * @throws KeyCrypterException * @throws UnsupportedEncodingException */ @Test public void testKeyCrypterGood2() throws Exception { KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(scryptParameters); System.out.print("EncrypterDecrypterTest: Trying random UUIDs for plainText and passwords :"); int numberOfTests = 16; for (int i = 0; i < numberOfTests; i++) { // Create a UUID as the plaintext and use another for the password. String plainText = UUID.randomUUID().toString(); CharSequence password = UUID.randomUUID().toString(); EncryptedPrivateKey encryptedPrivateKey = keyCrypter.encrypt(plainText.getBytes(), keyCrypter.deriveKey(password)); assertNotNull(encryptedPrivateKey); byte[] reconstructedPlainBytes = keyCrypter.decrypt(encryptedPrivateKey, keyCrypter.deriveKey(password)); assertEquals( Utils.bytesToHexString(plainText.getBytes()), Utils.bytesToHexString(reconstructedPlainBytes)); System.out.print('.'); } System.out.println(" Done."); }
@Test public void deterministicUpgradeEncrypted() throws Exception { group = new KeyChainGroup(params); final ECKey key = new ECKey(); group.importKeys(key); final KeyCrypterScrypt crypter = new KeyCrypterScrypt(); final KeyParameter aesKey = crypter.deriveKey("abc"); assertTrue(group.isDeterministicUpgradeRequired()); group.encrypt(crypter, aesKey); assertTrue(group.isDeterministicUpgradeRequired()); try { group.upgradeToDeterministic(0, null); fail(); } catch (DeterministicUpgradeRequiresPassword e) { // Expected. } group.upgradeToDeterministic(0, aesKey); assertFalse(group.isDeterministicUpgradeRequired()); final DeterministicSeed deterministicSeed = group.getActiveKeyChain().getSeed(); assertNotNull(deterministicSeed); assertTrue(deterministicSeed.isEncrypted()); byte[] entropy = checkNotNull(group.getActiveKeyChain().toDecrypted(aesKey).getSeed()).getEntropyBytes(); // Check we used the right key: oldest non rotating. byte[] truncatedBytes = Arrays.copyOfRange(key.getSecretBytes(), 0, 16); assertArrayEquals(entropy, truncatedBytes); }
@Test public void testEncryptDecryptBytes2() throws KeyCrypterException { KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(scryptParameters); // Encrypt random bytes of various lengths up to length 50. Random random = new Random(); for (int i = 0; i < 50; i++) { byte[] plainBytes = new byte[i]; random.nextBytes(plainBytes); EncryptedPrivateKey encryptedPrivateKey = keyCrypter.encrypt(plainBytes, keyCrypter.deriveKey(PASSWORD1)); assertNotNull(encryptedPrivateKey); // log.debug("\nEncrypterDecrypterTest: cipherBytes = \nlength = " + cipherBytes.length + // "\n---------------\n" + Utils.bytesToHexString(cipherBytes) + "\n---------------\n"); byte[] rebornPlainBytes = keyCrypter.decrypt(encryptedPrivateKey, keyCrypter.deriveKey(PASSWORD1)); log.debug("Original: (" + i + ") " + Utils.bytesToHexString(plainBytes)); log.debug("Reborn1 : (" + i + ") " + Utils.bytesToHexString(rebornPlainBytes)); assertEquals(Utils.bytesToHexString(plainBytes), Utils.bytesToHexString(rebornPlainBytes)); } }
@Test public void encryptionWhilstEmpty() throws Exception { group = new KeyChainGroup(params); group.setLookaheadSize(5); KeyCrypterScrypt scrypt = new KeyCrypterScrypt(2); final KeyParameter aesKey = scrypt.deriveKey("password"); group.encrypt(scrypt, aesKey); assertTrue(group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS).isEncrypted()); final ECKey key = group.currentKey(KeyChain.KeyPurpose.RECEIVE_FUNDS); group.decrypt(aesKey); assertFalse(checkNotNull(group.findKeyFromPubKey(key.getPubKey())).isEncrypted()); }
@Test public void testKeyCrypterGood1() throws KeyCrypterException { KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(scryptParameters); // Encrypt. EncryptedPrivateKey encryptedPrivateKey = keyCrypter.encrypt(TEST_BYTES1, keyCrypter.deriveKey(PASSWORD1)); assertNotNull(encryptedPrivateKey); // Decrypt. byte[] reborn = keyCrypter.decrypt(encryptedPrivateKey, keyCrypter.deriveKey(PASSWORD1)); log.debug("Original: " + Utils.bytesToHexString(TEST_BYTES1)); log.debug("Reborn : " + Utils.bytesToHexString(reborn)); assertEquals(Utils.bytesToHexString(TEST_BYTES1), Utils.bytesToHexString(reborn)); }
@Test public void serialization() throws Exception { assertEquals(INITIAL_KEYS + 1 /* for the seed */, group.serializeToProtobuf().size()); group = KeyChainGroup.fromProtobufUnencrypted(params, group.serializeToProtobuf()); group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS); DeterministicKey key1 = group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS); DeterministicKey key2 = group.freshKey(KeyChain.KeyPurpose.CHANGE); group.getBloomFilterElementCount(); List<Protos.Key> protoKeys1 = group.serializeToProtobuf(); assertEquals( INITIAL_KEYS + ((LOOKAHEAD_SIZE + 1) * 2) + 1 /* for the seed */ + 1, protoKeys1.size()); group.importKeys(new ECKey()); List<Protos.Key> protoKeys2 = group.serializeToProtobuf(); assertEquals( INITIAL_KEYS + ((LOOKAHEAD_SIZE + 1) * 2) + 1 /* for the seed */ + 2, protoKeys2.size()); group = KeyChainGroup.fromProtobufUnencrypted(params, protoKeys1); assertEquals( INITIAL_KEYS + ((LOOKAHEAD_SIZE + 1) * 2) + 1 /* for the seed */ + 1, protoKeys1.size()); assertTrue(group.hasKey(key1)); assertTrue(group.hasKey(key2)); assertEquals(key2, group.currentKey(KeyChain.KeyPurpose.CHANGE)); assertEquals(key1, group.currentKey(KeyChain.KeyPurpose.RECEIVE_FUNDS)); group = KeyChainGroup.fromProtobufUnencrypted(params, protoKeys2); assertEquals( INITIAL_KEYS + ((LOOKAHEAD_SIZE + 1) * 2) + 1 /* for the seed */ + 2, protoKeys2.size()); assertTrue(group.hasKey(key1)); assertTrue(group.hasKey(key2)); KeyCrypterScrypt scrypt = new KeyCrypterScrypt(2); final KeyParameter aesKey = scrypt.deriveKey("password"); group.encrypt(scrypt, aesKey); List<Protos.Key> protoKeys3 = group.serializeToProtobuf(); group = KeyChainGroup.fromProtobufEncrypted(params, protoKeys3, scrypt); assertTrue(group.isEncrypted()); assertTrue(group.checkPassword("password")); group.decrypt(aesKey); // No need for extensive contents testing here, as that's done in the keychain class tests. }
@Test public void testEncryptDecryptBytes1() throws KeyCrypterException { KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(scryptParameters); // Encrypt bytes. EncryptedPrivateKey encryptedPrivateKey = keyCrypter.encrypt(TEST_BYTES1, keyCrypter.deriveKey(PASSWORD1)); assertNotNull(encryptedPrivateKey); log.debug( "\nEncrypterDecrypterTest: cipherBytes = \nlength = " + encryptedPrivateKey.getEncryptedBytes().length + "\n---------------\n" + Utils.bytesToHexString(encryptedPrivateKey.getEncryptedBytes()) + "\n---------------\n"); byte[] rebornPlainBytes = keyCrypter.decrypt(encryptedPrivateKey, keyCrypter.deriveKey(PASSWORD1)); log.debug("Original: " + Utils.bytesToHexString(TEST_BYTES1)); log.debug("Reborn1 : " + Utils.bytesToHexString(rebornPlainBytes)); assertEquals(Utils.bytesToHexString(TEST_BYTES1), Utils.bytesToHexString(rebornPlainBytes)); }
@Test public void testKeyCrypterWrongPassword() throws KeyCrypterException { KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(scryptParameters); // create a longer encryption string StringBuilder stringBuffer = new StringBuilder(); for (int i = 0; i < 100; i++) { stringBuffer.append(i).append(" ").append("The quick brown fox"); } EncryptedPrivateKey encryptedPrivateKey = keyCrypter.encrypt(stringBuffer.toString().getBytes(), keyCrypter.deriveKey(PASSWORD2)); assertNotNull(encryptedPrivateKey); try { keyCrypter.decrypt(encryptedPrivateKey, keyCrypter.deriveKey(WRONG_PASSWORD)); // TODO: This test sometimes fails due to relying on padding. fail("Decrypt with wrong password did not throw exception"); } catch (KeyCrypterException ede) { assertTrue(ede.getMessage().contains("Could not decrypt")); } }
public void encryption(boolean withImported) throws Exception { Utils.rollMockClock(0); long now = Utils.currentTimeSeconds(); ECKey a = group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS); assertEquals(now, group.getEarliestKeyCreationTime()); Utils.rollMockClock(-86400); long yesterday = Utils.currentTimeSeconds(); ECKey b = new ECKey(); assertFalse(group.isEncrypted()); try { group.checkPassword("foo"); // Cannot check password of an unencrypted group. fail(); } catch (IllegalStateException e) { } if (withImported) { assertEquals(now, group.getEarliestKeyCreationTime()); group.importKeys(b); assertEquals(yesterday, group.getEarliestKeyCreationTime()); } KeyCrypterScrypt scrypt = new KeyCrypterScrypt(2); final KeyParameter aesKey = scrypt.deriveKey("password"); group.encrypt(scrypt, aesKey); assertTrue(group.isEncrypted()); assertTrue(group.checkPassword("password")); assertFalse(group.checkPassword("wrong password")); final ECKey ea = group.findKeyFromPubKey(a.getPubKey()); assertTrue(checkNotNull(ea).isEncrypted()); if (withImported) { assertTrue(checkNotNull(group.findKeyFromPubKey(b.getPubKey())).isEncrypted()); assertEquals(yesterday, group.getEarliestKeyCreationTime()); } else { assertEquals(now, group.getEarliestKeyCreationTime()); } try { ea.sign(Sha256Hash.ZERO_HASH); fail(); } catch (ECKey.KeyIsEncryptedException e) { // Ignored. } if (withImported) { ECKey c = new ECKey(); try { group.importKeys(c); fail(); } catch (KeyCrypterException e) { } group.importKeysAndEncrypt(ImmutableList.of(c), aesKey); ECKey ec = group.findKeyFromPubKey(c.getPubKey()); try { group.importKeysAndEncrypt(ImmutableList.of(ec), aesKey); fail(); } catch (IllegalArgumentException e) { } } try { group.decrypt(scrypt.deriveKey("WRONG PASSWORD")); fail(); } catch (KeyCrypterException e) { } group.decrypt(aesKey); assertFalse(group.isEncrypted()); assertFalse(checkNotNull(group.findKeyFromPubKey(a.getPubKey())).isEncrypted()); if (withImported) { assertFalse(checkNotNull(group.findKeyFromPubKey(b.getPubKey())).isEncrypted()); assertEquals(yesterday, group.getEarliestKeyCreationTime()); } else { assertEquals(now, group.getEarliestKeyCreationTime()); } }