Blankj/AndroidUtilCode · error · IllegalArgumentException

key must be between 1 and 256 bytes

Error message

key must be between 1 and 256 bytes

What it means

EncryptUtils.rc4(byte[], byte[]) implements the RC4 stream cipher, which initialises a 256-byte S-box keyed by repeating the supplied key. The RC4 specification requires a key of 1..256 bytes; a zero-length or over-long key would either divide-by-zero (keyLen=0 in key[i % keyLen]) or break the cipher's security assumptions, so the method fails fast with IllegalArgumentException. Note: a null key returns null earlier, and null/empty data also returns null.

Source

Thrown at lib/utilcode/src/main/java/com/blankj/utilcode/util/EncryptUtils.java:1145

            } else {
                return cipher.doFinal(data);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Return the bytes of RC4 encryption/decryption.
     *
     * @param data The data.
     * @param key  The key.
     */
    public static byte[] rc4(byte[] data, byte[] key) {
        if (data == null || data.length == 0 || key == null) return null;
        if (key.length < 1 || key.length > 256) {
            throw new IllegalArgumentException("key must be between 1 and 256 bytes");
        }
        final byte[] iS = new byte[256];
        final byte[] iK = new byte[256];
        int keyLen = key.length;
        for (int i = 0; i < 256; i++) {
            iS[i] = (byte) i;
            iK[i] = key[i % keyLen];
        }
        int j = 0;
        byte tmp;
        for (int i = 0; i < 256; i++) {
            j = (j + iS[i] + iK[i]) & 0xFF;
            tmp = iS[j];
            iS[j] = iS[i];
            iS[i] = tmp;
        }

        final byte[] ret = new byte[data.length];

View on GitHub (pinned to 7b4caf9e54)

Solutions

  1. Ensure the key is a properly derived 16/32-byte (or other 1..256) secret — e.g. feed a passphrase through a KDF (PBKDF2/HKDF) before calling rc4.
  2. Validate the key length at the boundary: if (key == null || key.length == 0 || key.length > 256) reject/derive before calling.
  3. If the key is hex/Base64-encoded text, decode it to bytes first (ConvertUtils.hexString2Bytes / Base64.decode) rather than passing getBytes().
  4. Avoid RC4 entirely for new code (it is cryptographically broken); prefer EncryptUtils.encryptAES(...) and use RC4 only for legacy interop with a known-correct key.

Example fix

// before
byte[] out = EncryptUtils.rc4(data, passphrase.getBytes()); // empty/over-long passphrase

// after
byte[] key = deriveKey(passphrase); // PBKDF2/HKDF -> 16..256 bytes
byte[] out = EncryptUtils.rc4(data, key);
Defensive patterns

Strategy: validation

Validate before calling

// Validate the RC4 key length before calling
byte[] key = derivedKey;
if (key == null || key.length == 0 || key.length > 256) {
    // derive a proper key (e.g. via PBKDF2/HKDF) instead of throwing
    key = deriveKey(passphrase, 16);
}
byte[] out = EncryptUtils.rc4(data, key);

Type guard

// RC4 key length guard
public static boolean isValidRc4Key(byte[] key) {
    return key != null && key.length >= 1 && key.length <= 256;
}

Try / catch

try {
    byte[] out = EncryptUtils.rc4(data, key);
} catch (IllegalArgumentException e) {
    // key length out of range; derive a valid key and retry
    byte[] fixed = deriveKey(passphrase, 16);
    out = EncryptUtils.rc4(data, fixed);
}

Prevention

When it happens

Trigger: Passing a key byte[] of length 0 (e.g. from an empty password or a config that yielded no bytes) or longer than 256 bytes (e.g. a raw RSA/HMAC key, a full certificate, or concatenated secrets). Decryption fails symmetrically because RC4 uses the same routine for both directions.

Common situations: Deriving the RC4 key from user input that was left empty; using a hex/Base64 string as the key without decoding; concatenating multiple key materials past the 256-byte ceiling; migrating from a 'no key check' RC4 implementation that silently accepted any length.

Related errors


AI-assisted analysis of Blankj/AndroidUtilCode@7b4caf9e54 (2026-08-14). Data as JSON: /api/errors/1274edc5c318fcca. Report an issue: GitHub.