0

I am using the below code

 public byte[] encrypt(byte[] unencryptedString,String k)throws Exception {
    String encryptedString = null;

    String k1 = String.format("%024d", Integer.parseInt(k));
    myEncryptionKey = k1;
    myEncryptionScheme = DESEDE_ENCRYPTION_SCHEME;
    arrayBytes = myEncryptionKey.getBytes(UNICODE_FORMAT);
    ks = new DESedeKeySpec(arrayBytes);
    skf = SecretKeyFactory.getInstance(myEncryptionScheme);
    cipher = Cipher.getInstance(myEncryptionScheme);
    key = skf.generateSecret(ks);

    try {
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] plainText =
                unencryptedString/*.getBytes(UNICODE_FORMAT)*/;
        byte[] encryptedText = cipher.doFinal(plainText);
       // encryptedString = new String(Base64.encodeBase64(encryptedText));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return encryptedText;
}

The return statement gives the following error:

encryptedText cannot be resolved to a variable

4
  • 4
    The scope of encryptedText is in the try block. You need to move the declaration. Commented Apr 19, 2016 at 15:47
  • @KevinO: Or the return statement. It's unlikely that returning null (or something similar) is actually the best course of action here. Commented Apr 19, 2016 at 15:51
  • @JonSkeet, agreed that returning null is a bad idea, and moving the return statement might be better, but it depends upon specifications outside the scope of the posted code. It is declared to throw a generic Exception, which is also a bad idea, but doesn't do so if there is an issue with the cipher.doFinal, so returning null would be the only indicator of a problem given the code, I think. Commented Apr 19, 2016 at 15:55
  • @KevinO: Indeed. I'm writing an answer addressing all of these. Commented Apr 19, 2016 at 15:56

4 Answers 4

2

Contrary to the other answers, I wouldn't change your code to return null if you fail to encrypt the text - I would let that failure bubble up as an exception. I wouldn't declare that your method can throw Exception either - I'd specify which exceptions it can throw. You could do this at a very fine-grained level, or in this case use GeneralSecurityException which covers all the crypto-specific exceptions you're interested in.

I'd further stop using fields unnecessarily - you don't need to change any state here.

After all this refactoring, your method would become:

public static byte[] encrypt(String unencryptedString, String k)
    throws GeneralSecurityException {
    String keySpecText = String.format("%024d", Integer.parseInt(k));
    byte[] keySpecBytes = keySpecText.getBytes(StandardCharsets.UTF_16);
    KeySpec ks = new DESedeKeySpec(keySpecBytes);
    SecretKeyFactory skf = SecretKeyFactory.getInstance(DESEDE_ENCRYPTION_SCHEME);
    Key key = skf.generateSecret(ks);
    Cipher cipher = Cipher.getInstance(DESEDE_ENCRYPTION_SCHEME);
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] plainText = unencryptedString.getBytes(StandardCharsets.UTF_16);
    return cipher.doFinal(plainText);
}

I'm not at all sure that this is a good way of providing a key - you're limited to 232 keys here, which isn't great, and even if you're happy with that, why take a string for the key instead of an int? But at least the code compiles, and when it fails it will properly fail.

Sign up to request clarification or add additional context in comments.

Comments

0

Declare the variable in the beginning of your scope, because in the try block it may not even exist. So you can't return smth. which may not exist.

Put it there

String encryptedString = null;
byte[] encryptedText

Comments

0

encrytpedText only has scope within your try block. Try this:

byte[] encrytpedText = null;
try {
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] plainText =
            unencryptedString/*.getBytes(UNICODE_FORMAT)*/;
    encryptedText = cipher.doFinal(plainText);
   // encryptedString = new String(Base64.encodeBase64(encryptedText));
} catch (Exception e) {
    e.printStackTrace();
}
return encryptedText;

Comments

0

Useful in AES all lengths 128, 192, 256 bits encryption.

Just change the KEY_LEN_IN_BITS static value.

Here we go -

private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
private static int ITERATIONS = 65536;
private static SecretKey secretKey = null;
final private static short KEY_LEN_IN_BITS = (short)128;
final private static byte[] BUFFER = new byte[1024 * 64];

private static byte[] generateSalt() throws NoSuchAlgorithmException {  
    Random random = SecureRandom.getInstance("SHA1PRNG");
    byte[] salt = new byte[8];
    random.nextBytes(salt);
    return salt;
}

static ArrayList<Object> encrypt256(final FileInputStream fis, final String encryptFileTarget, final String fileTitle, final String keyVal) throws Exception{

    final ArrayList<Object> encryptInfo = new ArrayList<Object>();

    try{
        byte[] saltBytes = new byte[8];
        saltBytes = generateSalt();

        SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec spec = new PBEKeySpec(keyVal.toCharArray(), saltBytes, ITERATIONS, KEY_LEN_IN_BITS);
        secretKey = skf.generateSecret(spec);
        SecretKey secret = new SecretKeySpec(secretKey.getEncoded(), "AES");//"ISO-8859-1"

        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secret);

        AlgorithmParameters params = cipher.getParameters ();
        byte[] initIVVector = params.getParameterSpec (IvParameterSpec.class).getIV();

        FileOutputStream fos = new FileOutputStream(encryptFileTarget, true);
        CipherOutputStream cos = new CipherOutputStream(fos, cipher);

        InputStream is = new BufferedInputStream(fis);
        int bytesRead = -1;
        int count = 0;

        while((bytesRead = is.read(BUFFER)) != -1){
            //System.out.println("bytesRead values is : " + bytesRead);
            cos.write(BUFFER, 0, bytesRead);
        }

        cos.flush();
        cos.close();
        is.close();
        fos.flush();
        fos.close();
        fis.close();

        encryptInfo.add(Hex.encodeHexString(initIVVector));
        encryptInfo.add(Hex.encodeHexString(saltBytes));

    }catch(Exception exp){
        exp.printStackTrace();
    }

    return encryptInfo;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.