initializeKeyPair returns an account id that is used to unlock an account:
case "unlockAccount":
{
String secretPhrase = req.getParameter("secretPhrase");
BigInteger accountId = user.initializeKeyPair(secretPhrase);
...
However, the account number is comprised of only the first 8 bytes of the hash of the account's public key:
BigInteger initializeKeyPair(String secretPhrase) throws Exception {
this.secretPhrase = secretPhrase;
byte[] publicKeyHash = MessageDigest.getInstance("SHA-256").digest(Crypto.getPublicKey(secretPhrase));
BigInteger bigInteger = new BigInteger(1, new byte[] {publicKeyHash[7], publicKeyHash[6], publicKeyHash[5], publicKeyHash[4], publicKeyHash[3], publicKeyHash[2], publicKeyHash[1], publicKeyHash[0]});
return bigInteger;
}
The SHA-256 hash is secure because it creates a 256-bit number and a negligible (albeit non-zero) hash collision probability. In practice, hash collisions can usually be ignored (although in this case since it is dealing with currency, the implications of a hash collision are especially concerning since people would be able to use other's money or block them from using their money.
However, by reducing the identifier from 256-bit to 32-bit the possibility for hash collisions is exponentially greater. Also, there's no guarantee that a hash algorithm (i.e. SHA-256) guarantees that subsets of its produced hashes are also hashes. What this means is that there's no guarantee that the first 32-bits of SHA-256 hashes are even as good as 32-bit hashes.
Even BitCoin addresses are much more secure in that they are 160-bit (real) hashes (
http://bitcoin.stackexchange.com/questions/7724/what-happens-if-your-bitcoin-client-generates-an-address-identical-to-another-pe).
I think it's critical that we make NXT at least as secure as Bitcoin.