/** * Calculate keyId for a given key (should be either {@link PublicKey} or {@link PrivateKey}). the keyId is the same * for public and private key and can be used to store/access keys in Map ({@link Bytes} instances can be used as * Map keys. * <p> * Use {@link #extractKeyId(byte[])} to get a keyId from a packed extended signature, find the proper key, than * {@link #verify(PublicKey, byte[], byte[])} the data. It uses corresponding {@link PublicKey#fingerprint()}. * * @param key key to calculate Id * * @return calculated key id */ static public Bytes keyId(AbstractKey key) { if (key instanceof PrivateKey) return new Bytes(key.getPublicKey().fingerprint()); return new Bytes(key.fingerprint()); }
/** * Check that the packed anonymousId matches current key. Use {@link #createAnonymousId()} to get a random anonymous * id for this key. * * @param packedId * @return true if it matches. * @throws IOException */ public boolean matchAnonymousId(@NonNull byte[] packedId) throws IOException { assert (packedId.length == 64); HMAC hmac = new HMAC(fingerprint()); hmac.update(packedId, 0, 32); byte[] idDigest = Arrays.copyOfRange(packedId, 32, 64); return Arrays.equals(hmac.digest(), idDigest); }
/** * Create a random (e.g. every call a different) sequence of bytes that identidy this key. There can almost infinite * number if anonynous ids for e key (more than 1.0E77), so it is really anonymous way to identify some key. The * anonymousId for public and private keys are the same. * <p> * Anonymous ID size is 64 bytes: first are 32 random bytes, last are HMAC(key, sha256) of these random bytes. * <p> * The most important thing about anonymous ids is that every time this call generates new id for the same key, * providing anonymous but exact identification of a key. * <p> * To check that the key matches some anonymousId, use {@link #matchAnonymousId(byte[])}. * <p> * Therefore, the private key fingerprint is its public key fingerprint. The public key fingerprint is calculated * using some hash over it's parameters, see {@link PublicKey#fingerprint()} * * @return */ public byte[] createAnonymousId() { byte[] rvector = Do.randomBytes(32); HMAC hmac = new HMAC(fingerprint()); hmac.update(rvector); byte[] result = new byte[64]; System.arraycopy(rvector, 0, result, 0, 32); System.arraycopy(hmac.digest(), 0, result, 32, 32); return result; }