JAVA: Method, Classes, Variables and Subprograms

1

From the main, I want to call a subprogram of a class, putting a parameter to it. I want to print it later.

public class main {

public static void main(String[] args) throws Exception {
String cleartext = "hola";
System.out.println(crypto.Cifrar.encrypt(cleartext.getBytes()));

}

}

This is my class that I have. Eye! I think I made a mess with the parameters, constructors and others. Let's see if you can try it and see what's wrong. Thanks.

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import static com.sun.org.apache.xerces.internal.impl.dv.util.Base64.encode;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public  class Cifrar {

// Definición del tipo de algoritmo a utilizar (AES, DES, RSA)
private final static String alg = "AES";
private final static int keyLength=128;
private final static int ivLength=128;
private final static String cI =  "AES/CBC/PKCS5Padding";
private byte [] iv;
private static byte[] aesKeyBytes;
private static IvParameterSpec ivParameterSpec;


public Cifrar() throws Exception {
    KeyGenerator keyGen = KeyGenerator.getInstance(alg);
    keyGen.init(keyLength, new SecureRandom());
    SecretKey aesKey = keyGen.generateKey();
    aesKeyBytes = aesKey.getEncoded();
    iv = SecureRandom.getSeed(ivLength / 8);
    IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

}
 public Cifrar(byte[]aesKeyBytesQuemePasan, IvParameterSpec ivspecquemePasan) throws NoSuchAlgorithmException {


    aesKeyBytes = aesKeyBytesQuemePasan;
    ivParameterSpec = ivspecquemePasan;

}

public void setAesKeyBytes(byte[] aesKeyBytes) {
    this.aesKeyBytes = aesKeyBytes;
}

public void setIv(byte[] iv) {
    this.iv = iv;
}  

public static byte[] encrypt(byte[] cleartext) throws Exception {
    Cipher cipher = Cipher.getInstance(cI);
    SecretKeySpec skeySpec = new SecretKeySpec(aesKeyBytes, alg);
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);
    byte[] encrypted = cipher.doFinal(cleartext);
    return encrypted;
}

public static byte[] decrypt( byte[] encrypted) throws Exception {
    Cipher cipher = Cipher.getInstance(cI);
    SecretKeySpec skeySpec = new SecretKeySpec(aesKeyBytes, alg);
    System.out.println(encrypted);
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);
    byte[] decrypted = cipher.doFinal(encrypted);
    return decrypted;
}

}

This is the fault it gives me:

Exception in thread "main" java.lang.IllegalArgumentException: Missing argument
at javax.crypto.spec.SecretKeySpec.<init>(SecretKeySpec.java:93)
at crypto.Cifrar.encrypt(Cifrar.java:64)
at crypto.main.main(main.java:22)

Thank you very much:)

    
asked by Solid 30.05.2017 в 20:17
source

1 answer

0

NOTE: It is better to indicate in the code which is the line of your program where the fault is (in this case line 64).

The bug arises in the constructor of SecretKeySpec . We go to the Javadoc , which tells us:

  

Throws:

     

IllegalArgumentException - if algorithm is null or key is null or empty.

Reviewing the code, it appears:

public static byte[] encrypt(byte[] cleartext) throws Exception {
  Cipher cipher = Cipher.getInstance(cI);
  SecretKeySpec skeySpec = new SecretKeySpec(aesKeyBytes, alg);

alg is static final and has the value "AES". But at no time is a value assigned to aesKeyBytes .

The problem is that the class is a mixture of static and instance methods and attributes. If encrypt and decrypt were instance methods (not static), you would invoke them on an instance of Cifrar properly initialized, with one of the two constructors, and in the constructors the value of aesKeyBytes would be assigned (assuming that you will not pass an array null , of course).

As it is, there is a code in the constructors that assigns the value of the key, but since the methods are invoked directly as static methods, no constructor is executed with the initialization.

Solution: Remove all static from the class so that all methods and attributes are instance, create an instance of Cifrar and call its methods encrypt and decrypt .

    
answered by 30.05.2017 / 21:26
source