diff --git a/src/net/java/sip/communicator/impl/credentialsstorage/AESCrypto.java b/src/net/java/sip/communicator/impl/credentialsstorage/AESCrypto.java index 8fda279c2..f1f83b1ad 100644 --- a/src/net/java/sip/communicator/impl/credentialsstorage/AESCrypto.java +++ b/src/net/java/sip/communicator/impl/credentialsstorage/AESCrypto.java @@ -40,9 +40,9 @@ public class AESCrypto { 0x0C, 0x0A, 0x0F, 0x0E, 0x0B, 0x0E, 0x0E, 0x0F }; /** - * Length of the key in bits. + * Possible length of the keys in bits. */ - private static int KEY_LENGTH = 256; + private static int[] KEY_LENGTHS = new int[]{256, 128}; /** * Number of iterations to use when creating the key. @@ -71,30 +71,32 @@ public class AESCrypto */ public AESCrypto(String masterPassword) { - // if the password is empty, we get an exception constructing the key - if (masterPassword == null) - { - // here a default password can be set, - // cannot be an empty string - masterPassword = " "; - } - try { decryptCipher = Cipher.getInstance(CIPHER_ALGORITHM); encryptCipher = Cipher.getInstance(CIPHER_ALGORITHM); - - // Password-Based Key Derivation Function found in PKCS5 v2.0. - // This is only available with java 6. - SecretKeyFactory factory = - SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); - // Make a key from the master password - KeySpec spec = - new PBEKeySpec(masterPassword.toCharArray(), SALT, - ITERATION_COUNT, KEY_LENGTH); - SecretKey tmp = factory.generateSecret(spec); - // Make an algorithm specific key - key = new SecretKeySpec(tmp.getEncoded(), KEY_ALGORITHM); + + // we try init of key with suupplied lengths + // we stop after the first successful attempt + for (int i = 0; i < KEY_LENGTHS.length; i++) + { + try + { + initKey(masterPassword, KEY_LENGTHS[i]); + + // its ok stop trying + break; + } + catch (InvalidKeyException e) + { + if(i == KEY_LENGTHS.length - 1) + throw e; + } + } + } + catch (InvalidKeyException e) + { + throw new RuntimeException("Invalid key", e); } catch (InvalidKeySpecException e) { @@ -110,6 +112,41 @@ public AESCrypto(String masterPassword) } } + /** + * Initialize key with specified length. + * + * @param masterPassword used to derive the key. Can be null. + * @param keyLength Length of the key in bits. + * @throws InvalidKeyException + * @throws NoSuchAlgorithmException + * @throws InvalidKeySpecException + */ + private void initKey(String masterPassword, int keyLength) + throws InvalidKeyException, + NoSuchAlgorithmException, + InvalidKeySpecException + { + // if the password is empty, we get an exception constructing the key + if (masterPassword == null) + { + // here a default password can be set, + // cannot be an empty string + masterPassword = " "; + } + + // Password-Based Key Derivation Function found in PKCS5 v2.0. + // This is only available with java 6. + SecretKeyFactory factory = + SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); + // Make a key from the master password + KeySpec spec = + new PBEKeySpec(masterPassword.toCharArray(), SALT, + ITERATION_COUNT, keyLength); + SecretKey tmp = factory.generateSecret(spec); + // Make an algorithm specific key + key = new SecretKeySpec(tmp.getEncoded(), KEY_ALGORITHM); + } + /** * Decrypts the cyphertext using the key. * diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java index 0c7ec1a95..a122679ed 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java @@ -317,7 +317,7 @@ private synchronized void connectAndLogin(SecurityAuthority authority, { //verify whether a password has already been stored for this account String password = JabberActivator. - getProtocolProviderFactory().loadPassword(getAccountID()); + getProtocolProviderFactory().loadPassword(getAccountID()); //decode if (password == null) @@ -1008,11 +1008,14 @@ private void fireRegistrationStateChanged(XMPPException ex) // we try determine the reason according to their message // all messages that were found in smack 3.1.0 were took in count if(exMsg.indexOf("authentication failed") != -1 + || (exMsg.indexOf("authentication") != -1 + && exMsg.indexOf("failed") != -1) || exMsg.indexOf("login failed") != -1 || exMsg.indexOf("unable to determine password") != -1) { JabberActivator.getProtocolProviderFactory(). storePassword(getAccountID(), null); + reason = RegistrationStateChangeEvent .REASON_AUTHENTICATION_FAILED;