mardi 1 septembre 2015

How to unit test exceptions when dealing with Cipher

How would one test Exceptions when working with Ciphers ? I thought at first it should be something simple as specifying some non-existing algorithm or padding but to my surprise this Cipher is resilient beast, simply refuses to throw an exception.

@Service
public class RsaClient

private Cipher cipher;
private PrivateKey privateKey;

private static final String CIPHER_SPECIFICATION ="RSA/None/NoPadding";
private static final String ALGORITHM_PROVIDER ="BC";

// ...


@Override
public String decrypt(String input) {

    // removes base64 encoding
    byte[] decoded = Base64Utils.decodeFromString(input);

    try {

        synchronized (cipher) {

            return new String(cipher.doFinal(decoded), StandardCharsets.UTF_8);
        }

       // how to trigger this reliably ?
    } catch (IllegalBlockSizeException | BadPaddingException e) { 

        throw new IllegalArgumentException(e.getMessage()); 
    } 
}


private Cipher getCipher() {

    try 
    {
        Cipher rsaCipher = Cipher.getInstance(CIPHER_SPECIFICATION, ALGORITHM_PROVIDER);
        rsaCipher.init(Cipher.DECRYPT_MODE, privateKey);
        return rsaCipher;
    }

       // how to trigger this reliably ?
    catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException | InvalidKeyException e) {

        throw new IllegalArgumentException(e.getMessage()); 
    } 
}

Here is one of my attempts to make getCipher throw an exception, note that the Test class has autowired Interface which RSAClient implements although this is not shown in code snippet:

@Test
public void testEncryptionError() {

    try {

        Field f = decryptor.getClass().getDeclaredField("CIPHER_SPECIFICATION");
        f.setAccessible(true);

        // ignore final modifier
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);

        // should cause exception when getCipher is invoked
        f.set(decryptor, null);

        Method initCipher = decryptor.getClass().getDeclaredMethod("getCipher");
        initCipher.setAccessible(true);
        initCipher.invoke(decryptor);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

How to test methods getCipher and decrypt? I have tried adjusting CIPHER_SPECIFICATION and ALGORITHM_PROVIDER from null to random words via reflection but it would always execute without exceptions.

Aucun commentaire:

Enregistrer un commentaire