@Test public void passwordProtectedJsCompatibilityTest() throws Exception { byte[] encrypted = Base64.decodeCompactString("NhDIoIYBvB1jb20uaWNvZGljaS5jcnlwdG8uUHJpdmF0ZUtleVtITUFDX1NIQTI1NsQaAe01NLf/Ffcye5nVmAOsYV5uy/Q/OXqbVfH4baSo5rgdtYl3xmTrkwfHEerHVjyB/raQcJ6b96k3oVIHu6I/wDtZ3TMkQ8gpjzlEnzOs6LQ+0OzObrjxFfpiXZdPMLzu4XPMSJINSZtkPkSOeBEqItCf2C2CfPgdI1MniiDAN9qmuWMuGkD4o6UgaGfCjy0WGv8vY0rgkkQUanf8ctcIEgbLCcpu2irJY+OUhh1qC+Dwm3uSDFarXC/94i/YWpSbo2Apyxjq6ynpXVyc2aQiOmOf13iHulq5t9eyoqP4uSXL4xHff23onQRnvvc4OC+vbQvHType64zPTxVCFDpw6rlUhT/bEJ6IOh8XhX+LHZeTEuaTy0LXE055xiT1P375"); byte[] packed = Base64.decodeCompactString("JgAcAQABvIEA96FWTEq/Wjmd7kYbx04I/Ax3OQV+6e4YWu7xBr8k/SexvYvFEE3c9dRsZSsEj7KzYrNpIXezCsxO+j1sHADmeojwuveDdQQM6M6fbvygHq/mxKGllDoJTpzX/CnkuXDwC+lpRkkMTIF48GaYDM525951HYW1pAIYaVr+V5ctVQW8gQDGM71OC1yBLv6n23dEuu9Vqna2lvDpEWNO7MgKY0Ri9vUPwp+F+dUiKsRTbjnukDFqiYiNj+jkcWgiXqnjqdAGf9LUWHfF80W1PwUhkFw7torLJfaAr6bZ6FRzGcxTMad0x7Rz+5lkBjliKqOt8AUAIvMVe45G0c0StJSoqdqc4Q=="); PrivateKey pk1 = PrivateKey.unpackWithPassword(encrypted,"some-password"); PrivateKey pk2 = new PrivateKey(packed); assertEquals(pk1,pk2); try { PrivateKey.unpackWithPassword(encrypted,"some-password1"); fail("should throw"); } catch (PrivateKey.PasswordProtectedException e) { } }
public static PrivateKey unpackWithPassword(byte[] packedBinary, String password) throws EncryptionError { List params = Boss.load(packedBinary); if ((Integer) params.get(0) == TYPE_PRIVATE) { return new PrivateKey(packedBinary); } else if ((Integer) params.get(0) == TYPE_PUBLIC) { throw new EncryptionError("the key is public, not private"); } else if ((Integer) params.get(0) == TYPE_PRIVATE_PASSWORD) { try { int rounds = (int) params.get(1); Bytes salt = (Bytes) params.get(2); String function = (String) params.get(3); Bytes packedEncryptedKey = (Bytes) params.get(4); Bytes digest = (Bytes) params.get(5); SymmetricKey key = new KeyInfo(KeyInfo.PRF.valueOf(function), rounds, salt.getData(), null) .derivePassword(password); byte[] packedKey = key.decrypt(packedEncryptedKey.getData()); byte[] resDigest = new Crc32().update(packedKey).digest(); if (!digest.equals(new Bytes(resDigest))) { throw new PasswordProtectedException("wrong password"); } return new PrivateKey(packedKey); } catch (Exception e) { if (e instanceof PasswordProtectedException) throw e; throw new EncryptionError("failed to parse password protected private key", e); } } else if ((Integer) params.get(0) == TYPE_PRIVATE_PASSWORD_V2) { try { KeyInfo keyInfo = new KeyInfo(((Bytes)params.get(1)).getData()); SymmetricKey key = keyInfo .derivePassword(password); byte[] packedKey = key.etaDecrypt(((Bytes) params.get(2)).getData()); return new PrivateKey(packedKey); } catch (SymmetricKey.AuthenticationFailed authenticationFailed) { throw new PasswordProtectedException("wrong password"); } catch (Exception e) { throw new EncryptionError("failed to parse password protected private key"); } } else { throw new EncryptionError("Bad or unknown private key type"); } }
PrivateKey extends AbstractKey { public static PrivateKey unpackWithPassword(byte[] packedBinary, String password) throws EncryptionError { List params = Boss.load(packedBinary); if ((Integer) params.get(0) == TYPE_PRIVATE) { return new PrivateKey(packedBinary); } else if ((Integer) params.get(0) == TYPE_PUBLIC) { throw new EncryptionError("the key is public, not private"); } else if ((Integer) params.get(0) == TYPE_PRIVATE_PASSWORD) { try { int rounds = (int) params.get(1); Bytes salt = (Bytes) params.get(2); String function = (String) params.get(3); Bytes packedEncryptedKey = (Bytes) params.get(4); Bytes digest = (Bytes) params.get(5); SymmetricKey key = new KeyInfo(KeyInfo.PRF.valueOf(function), rounds, salt.getData(), null) .derivePassword(password); byte[] packedKey = key.decrypt(packedEncryptedKey.getData()); byte[] resDigest = new Crc32().update(packedKey).digest(); if (!digest.equals(new Bytes(resDigest))) { throw new PasswordProtectedException("wrong password"); } return new PrivateKey(packedKey); } catch (Exception e) { if (e instanceof PasswordProtectedException) throw e; throw new EncryptionError("failed to parse password protected private key", e); } } else if ((Integer) params.get(0) == TYPE_PRIVATE_PASSWORD_V2) { try { KeyInfo keyInfo = new KeyInfo(((Bytes)params.get(1)).getData()); SymmetricKey key = keyInfo .derivePassword(password); byte[] packedKey = key.etaDecrypt(((Bytes) params.get(2)).getData()); return new PrivateKey(packedKey); } catch (SymmetricKey.AuthenticationFailed authenticationFailed) { throw new PasswordProtectedException("wrong password"); } catch (Exception e) { throw new EncryptionError("failed to parse password protected private key"); } } else { throw new EncryptionError("Bad or unknown private key type"); } } }
PrivateKey extends AbstractKey { public static PrivateKey unpackWithPassword(byte[] packedBinary, String password) throws EncryptionError { List params = Boss.load(packedBinary); if ((Integer) params.get(0) == TYPE_PRIVATE) { return new PrivateKey(packedBinary); } else if ((Integer) params.get(0) == TYPE_PUBLIC) { throw new EncryptionError("the key is public, not private"); } else if ((Integer) params.get(0) == TYPE_PRIVATE_PASSWORD) { try { int rounds = (int) params.get(1); Bytes salt = (Bytes) params.get(2); String function = (String) params.get(3); Bytes packedEncryptedKey = (Bytes) params.get(4); Bytes digest = (Bytes) params.get(5); SymmetricKey key = new KeyInfo(KeyInfo.PRF.valueOf(function), rounds, salt.getData(), null) .derivePassword(password); byte[] packedKey = key.decrypt(packedEncryptedKey.getData()); byte[] resDigest = new Crc32().update(packedKey).digest(); if (!digest.equals(new Bytes(resDigest))) { throw new PasswordProtectedException("wrong password"); } return new PrivateKey(packedKey); } catch (Exception e) { if (e instanceof PasswordProtectedException) throw e; throw new EncryptionError("failed to parse password protected private key", e); } } else if ((Integer) params.get(0) == TYPE_PRIVATE_PASSWORD_V2) { try { KeyInfo keyInfo = new KeyInfo(((Bytes)params.get(1)).getData()); SymmetricKey key = keyInfo .derivePassword(password); byte[] packedKey = key.etaDecrypt(((Bytes) params.get(2)).getData()); return new PrivateKey(packedKey); } catch (SymmetricKey.AuthenticationFailed authenticationFailed) { throw new PasswordProtectedException("wrong password"); } catch (Exception e) { throw new EncryptionError("failed to parse password protected private key"); } } else { throw new EncryptionError("Bad or unknown private key type"); } } PrivateKey(byte[] packedBinaryKey, KeyInfo info);  PrivateKey(byte[] packedBinaryKey);  PrivateKey(int bitStrength);  PrivateKey(); }
PrivateKey extends AbstractKey { public static PrivateKey unpackWithPassword(byte[] packedBinary, String password) throws EncryptionError { List params = Boss.load(packedBinary); if ((Integer) params.get(0) == TYPE_PRIVATE) { return new PrivateKey(packedBinary); } else if ((Integer) params.get(0) == TYPE_PUBLIC) { throw new EncryptionError("the key is public, not private"); } else if ((Integer) params.get(0) == TYPE_PRIVATE_PASSWORD) { try { int rounds = (int) params.get(1); Bytes salt = (Bytes) params.get(2); String function = (String) params.get(3); Bytes packedEncryptedKey = (Bytes) params.get(4); Bytes digest = (Bytes) params.get(5); SymmetricKey key = new KeyInfo(KeyInfo.PRF.valueOf(function), rounds, salt.getData(), null) .derivePassword(password); byte[] packedKey = key.decrypt(packedEncryptedKey.getData()); byte[] resDigest = new Crc32().update(packedKey).digest(); if (!digest.equals(new Bytes(resDigest))) { throw new PasswordProtectedException("wrong password"); } return new PrivateKey(packedKey); } catch (Exception e) { if (e instanceof PasswordProtectedException) throw e; throw new EncryptionError("failed to parse password protected private key", e); } } else if ((Integer) params.get(0) == TYPE_PRIVATE_PASSWORD_V2) { try { KeyInfo keyInfo = new KeyInfo(((Bytes)params.get(1)).getData()); SymmetricKey key = keyInfo .derivePassword(password); byte[] packedKey = key.etaDecrypt(((Bytes) params.get(2)).getData()); return new PrivateKey(packedKey); } catch (SymmetricKey.AuthenticationFailed authenticationFailed) { throw new PasswordProtectedException("wrong password"); } catch (Exception e) { throw new EncryptionError("failed to parse password protected private key"); } } else { throw new EncryptionError("Bad or unknown private key type"); } } PrivateKey(byte[] packedBinaryKey, KeyInfo info);  PrivateKey(byte[] packedBinaryKey);  PrivateKey(int bitStrength);  PrivateKey(); @Override boolean canSign(); @Override boolean isPrivate(); @Override byte[] decrypt(final byte[] encrypted); PublicKey getPublicKey(); byte[] pack(); @Override byte[] sign(InputStream input, HashType hashType); @Override KeyInfo info(); @Override boolean equals(Object obj); @Override int hashCode(); @Override byte[] fingerprint(); static PrivateKey fromPath(Path path); @Override Digest updateDigestWithKeyComponents(Digest digest); byte[] packWithPassword(String password); byte[] packWithPassword(String password, int rounds); static PrivateKey unpackWithPassword(byte[] packedBinary, String password); }
PrivateKey extends AbstractKey { public static PrivateKey unpackWithPassword(byte[] packedBinary, String password) throws EncryptionError { List params = Boss.load(packedBinary); if ((Integer) params.get(0) == TYPE_PRIVATE) { return new PrivateKey(packedBinary); } else if ((Integer) params.get(0) == TYPE_PUBLIC) { throw new EncryptionError("the key is public, not private"); } else if ((Integer) params.get(0) == TYPE_PRIVATE_PASSWORD) { try { int rounds = (int) params.get(1); Bytes salt = (Bytes) params.get(2); String function = (String) params.get(3); Bytes packedEncryptedKey = (Bytes) params.get(4); Bytes digest = (Bytes) params.get(5); SymmetricKey key = new KeyInfo(KeyInfo.PRF.valueOf(function), rounds, salt.getData(), null) .derivePassword(password); byte[] packedKey = key.decrypt(packedEncryptedKey.getData()); byte[] resDigest = new Crc32().update(packedKey).digest(); if (!digest.equals(new Bytes(resDigest))) { throw new PasswordProtectedException("wrong password"); } return new PrivateKey(packedKey); } catch (Exception e) { if (e instanceof PasswordProtectedException) throw e; throw new EncryptionError("failed to parse password protected private key", e); } } else if ((Integer) params.get(0) == TYPE_PRIVATE_PASSWORD_V2) { try { KeyInfo keyInfo = new KeyInfo(((Bytes)params.get(1)).getData()); SymmetricKey key = keyInfo .derivePassword(password); byte[] packedKey = key.etaDecrypt(((Bytes) params.get(2)).getData()); return new PrivateKey(packedKey); } catch (SymmetricKey.AuthenticationFailed authenticationFailed) { throw new PasswordProtectedException("wrong password"); } catch (Exception e) { throw new EncryptionError("failed to parse password protected private key"); } } else { throw new EncryptionError("Bad or unknown private key type"); } } PrivateKey(byte[] packedBinaryKey, KeyInfo info);  PrivateKey(byte[] packedBinaryKey);  PrivateKey(int bitStrength);  PrivateKey(); @Override boolean canSign(); @Override boolean isPrivate(); @Override byte[] decrypt(final byte[] encrypted); PublicKey getPublicKey(); byte[] pack(); @Override byte[] sign(InputStream input, HashType hashType); @Override KeyInfo info(); @Override boolean equals(Object obj); @Override int hashCode(); @Override byte[] fingerprint(); static PrivateKey fromPath(Path path); @Override Digest updateDigestWithKeyComponents(Digest digest); byte[] packWithPassword(String password); byte[] packWithPassword(String password, int rounds); static PrivateKey unpackWithPassword(byte[] packedBinary, String password);  }