Java Encryption Class

I have a problem in this code I need to find it out.
I am not into programming but I need to solve this thing and IDE won't help me :

import java.util.Base64;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Cipher {
    private static final String SECRET = "MyEncryptionKey1";
    private static byte[] getKey() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < SECRET.length(); i++) {
            sb.append((char) (SECRET.charAt(i) - (i * 2)));
        }
        return sb.toString().getBytes();
    }

    public static javax.crypto.Cipher getCipher(int i) {
        try {
            SecretKeySpec secretKeySpec = new SecretKeySpec(getKey(), "AES");
            javax.crypto.Cipher instance = javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding");
            instance.init(i, secretKeySpec, new IvParameterSpec(getKey()));
            return instance;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String encrypt(String str) {
        try {
            return Base64.encodeToString(getCipher(1).doFinal(str.getBytes()), 0);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String decrypt(String str) {
        try {
            return new String(getCipher(2).doFinal(Base64.decode(str, 0)));
        } catch (Exception e)
 {
            throw new RuntimeException(e);
        }
    }
}

1 answer

  • answered 2020-06-27 09:34 Michael Fehr

    I changed your code a little and added 2 methods for checking your environment, kindly run the code and present it to us as it will show the reason for your trouble.

    That's the result on my console output when using the 16 char long SECRET:

    keylength:     16
    Java version:  main: 11 major: 0 minor: 6+8 update: 520 build: 43
    restricted crypto: false - 'false' mean unlimited crypto that is good
    plaintext:     secret for encryption
    ciphertext:    ml/CO+9bYers//AW2v1bneE7RJnyZoaE5ThEYnYLzqo=
    decryptedtext: secret for encryption
    

    code:

    import java.security.NoSuchAlgorithmException;
    import java.util.Base64;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
    public class Cipher {
        private static final String SECRET = "MyEncryptionKey1";
    
        public static void main(String[] args) {
            System.out.println("keylength:     " + getKey().length);
            System.out.println("Java version:  " + getJavaVersion());
            System.out.println("restricted crypto: " + restrictedCryptography() + " - 'false' mean unlimited crypto that is good");
            String plaintext = "secret for encryption";
            String ciphertext = encrypt(plaintext);
            String decryptedtext = decrypt(ciphertext);
            System.out.println("plaintext:     " + plaintext);
            System.out.println("ciphertext:    " + ciphertext);
            System.out.println("decryptedtext: " + decryptedtext);
        }
    
        private static byte[] getKey() {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < SECRET.length(); i++) {
                sb.append((char) (SECRET.charAt(i) - (i * 2)));
            }
            return sb.toString().getBytes();
        }
    
        public static javax.crypto.Cipher getCipher(int i) {
            try {
                SecretKeySpec secretKeySpec = new SecretKeySpec(getKey(), "AES");
                javax.crypto.Cipher instance = javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding");
                instance.init(i, secretKeySpec, new IvParameterSpec(getKey()));
                return instance;
            } catch (Exception e) {
                System.out.println("Exception in getCipher: " + e);
                throw new RuntimeException(e);
            }
        }
    
        public static String encrypt(String str) {
            try {
                //return Base64.encodeToString(getCipher(1).doFinal(str.getBytes()), 0);
                return Base64.getEncoder().encodeToString(getCipher(1).doFinal(str.getBytes()));
            } catch (Exception e) {
                System.out.println("Exception in encrypt: " + e);
                throw new RuntimeException(e);
            }
        }
    
        public static String decrypt(String str) {
            try {
                //return new String(getCipher(2).doFinal(Base64.decode(str, 0)));
                return new String(getCipher(2).doFinal(Base64.getDecoder().decode(str)));
            } catch (Exception e)
            {
                System.out.println("Exception in decrypt: " + e);
                throw new RuntimeException(e);
            }
        }
    
        public static String getJavaVersion() {
            String[] javaVersionElements = System.getProperty("java.runtime.version").split("\\.|_|-b");
            String main, major, minor, update, build;
            main    = javaVersionElements[0];
            major   = javaVersionElements[1];
            minor   = javaVersionElements[2];
            update  = javaVersionElements[3];
            build   = javaVersionElements[4];
            return "main: " + main + " major: " + major + " minor: " + minor + " update: " + update + " build: " + build;
        }
    
        /**
         * Determines if cryptography restrictions apply.
         * Restrictions apply if the value of {@link javax.crypto.Cipher#getMaxAllowedKeyLength(String)} returns a value smaller than {@link Integer#MAX_VALUE} if there are any restrictions according to the JavaDoc of the method.
         * This method is used with the transform <code>"AES/CBC/PKCS5Padding"</code> as this is an often used algorithm that is <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#impl">an implementation requirement for Java SE</a>.
         *
         * @return <code>true</code> if restrictions apply, <code>false</code> otherwise
         * https://stackoverflow.com/posts/33849265/edit, author Maarten Bodewes
         */
        public static boolean restrictedCryptography() {
            try {
                return javax.crypto.Cipher.getMaxAllowedKeyLength("AES/CBC/PKCS5Padding") < Integer.MAX_VALUE;
            } catch (final NoSuchAlgorithmException e) {
                throw new IllegalStateException("The transform \"AES/CBC/PKCS5Padding\" is not available (the availability of this algorithm is mandatory for Java SE implementations)", e);
            }
        }
    }