private void checkSanity() { switch (algorythm) { case RSAPrivate: case RSAPublic: if (isPassword()) throw new IllegalArgumentException("RSA keys can't be password-derived"); break; case AES256: keyLength = 32; } if (isPassword()) { if (rounds < 100) throw new IllegalArgumentException("should be more than 1000 rounds for PRF"); if (keyLength < 16) throw new IllegalArgumentException("key should be at least 16 bytes for PRF"); if (salt == null) salt = "attesta".getBytes(); } }
@Override public Collection<AbstractKey> findKey(KeyInfo keyInfo) { ArrayList<AbstractKey> list = new ArrayList<>(); if (keyInfo.isPassword()) list.add(keyInfo.derivePassword(password)); return list; } };
public SymmetricKey derivePassword(String password) { if (!isPassword()) throw new IllegalStateException("not the PRF keyInfo"); Class<? extends Digest> cls; switch (prf) { case HMAC_SHA1: cls = Sha1.class; break; case HMAC_SHA256: cls = Sha256.class; break; case HMAC_SHA512: cls = Sha512.class; break; default: throw new IllegalArgumentException("unknown hash scheme for pbkdf2"); } byte[] key = PBKDF2.derive(cls, password, salt, rounds, keyLength); return new SymmetricKey(key, this); }
public byte[] pack() { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); Boss.Writer w = new Boss.Writer(baos); try { w.write(algorythm.ordinal(), tag, prf.ordinal(), keyLength); if (isPassword()) { w.write(0, rounds); } w.close(); return baos.toByteArray(); } catch (IOException e) { throw new RuntimeException("unexpected IO exception", e); } }
public KeyInfo(byte[] packedInfo) throws IOException { Boss.Reader r = new Boss.Reader(packedInfo); algorythm = Algorythm.values()[r.readInt()]; tag = r.readBinary(); prf = PRF.values()[r.readInt()]; keyLength = r.readInt(); if (isPassword()) { if (r.readInt() != 0) throw new IllegalArgumentException("unknown PBKDF type"); rounds = r.readInt(); } checkSanity(); }