How to encrypt String in Java

后端 未结 16 1238
梦毁少年i
梦毁少年i 2020-11-22 09:58

What I need is to encrypt string which will show up in 2D barcode(PDF-417) so when someone get an idea to scan it will get nothing readable.

Other requirements:

相关标签:
16条回答
  • 2020-11-22 10:24
    public static String encryptParams(String myTextInput) {
    
            String myKey = "40674244454045cb9a70040a30e1c007";
            String myVector = "@1B2c3D4e5F6g7H8";
    
            String encData = "";
    
            try{
                JavaEncryprtionUtil encUtil = new JavaEncryprtionUtil();
                encData = Base64.encodeToString(encUtil.encrypt(myTextInput.getBytes("UTF-8"), myKey.getBytes("UTF-8"), myVector.getBytes("UTF-8")),Base64.DEFAULT);
                System.out.println(encData);
            }catch(NoSuchAlgorithmException ex){
                ex.printStackTrace();
            }catch(NoSuchPaddingException ex){
                ex.printStackTrace();
            }catch(InvalidKeyException ex){
                ex.printStackTrace();
            }catch(InvalidAlgorithmParameterException ex){
                ex.printStackTrace();
            }catch(IllegalBlockSizeException ex){
                ex.printStackTrace();
            }catch(BadPaddingException ex){
                ex.printStackTrace();
            }catch(UnsupportedEncodingException ex){
                ex.printStackTrace();
            }
    
            return encData;
        }
    
    0 讨论(0)
  • 2020-11-22 10:27

    Here is a copy/paste solution. I also recommend reading and voting for @Konstantino's answer even though it doesn't provider any code. The initialization vector (IV) is like a salt - it doesn't have to be kept secret. I am new to GCM and apparently AAD is optional and only used in certain circumstances. Set the key in the environment variable SECRET_KEY_BASE. Use something like KeePass to generate a 32 character password. This solution is modeled after my Ruby solution.

        public static String encrypt(String s) {
            try {
                byte[] input = s.getBytes("UTF-8");
                String keyString = System.getProperty("SECRET_KEY_BASE", System.getenv("SECRET_KEY_BASE"));
                if (keyString == null || keyString.length() == 0) {
                    Logger.error(Utils.class, "encrypt()", "$SECRET_KEY_BASE is not set.");
                    return null;
                }
                byte[] keyBytes = keyString.getBytes("UTF-8");
                SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
                // generate IV
                SecureRandom secureRandom = SecureRandom.getInstanceStrong();
                Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
                byte[] ivBytes = new byte[cipher.getBlockSize()];
                secureRandom.nextBytes(ivBytes);
                GCMParameterSpec gcmSpec = new GCMParameterSpec(96, ivBytes); // 96 bit tag length
                cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmSpec);
                // generate AAD
    //          byte[] aadBytes = new byte[cipher.getBlockSize()];
    //          secureRandom.nextBytes(aadBytes);
    //          cipher.updateAAD(aadBytes);
                // encrypt
                byte[] encrypted = cipher.doFinal(input);
                byte[] returnBytes = new byte[ivBytes.length + encrypted.length];
    //          byte[] returnBytes = new byte[ivBytes.length + aadBytes.length + encrypted.length];
                System.arraycopy(ivBytes, 0, returnBytes, 0, ivBytes.length);
    //          System.arraycopy(aadBytes, 0, returnBytes, ivBytes.length, aadBytes.length);
                System.arraycopy(encrypted, 0, returnBytes, ivBytes.length, encrypted.length);
    //          System.arraycopy(encrypted, 0, returnBytes, ivBytes.length+aadBytes.length, encrypted.length);
                String encryptedString = Base64.getEncoder().encodeToString(returnBytes);
                return encryptedString;
            } catch (UnsupportedEncodingException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | 
                    InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
                Logger.error(Utils.class, "encrypt()", "Could not encrypt string: " + e.getMessage());
                return null;
            }
        }
    
        public static String decrypt(String s) {
            if (s == null || s.length() == 0) return "";
            try {
                byte[] encrypted = Base64.getDecoder().decode(s);
                String keyString = System.getProperty("SECRET_KEY_BASE", System.getenv("SECRET_KEY_BASE"));
                if (keyString == null || keyString.length() == 0) {
                    Logger.error(Utils.class, "encrypt()", "$SECRET_KEY_BASE is not set.");
                    return null;
                }
                byte[] keyBytes = keyString.getBytes("UTF-8");
                SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
                Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
                byte[] ivBytes = new byte[cipher.getBlockSize()];
                System.arraycopy(encrypted, 0, ivBytes, 0, ivBytes.length);
                GCMParameterSpec gcmSpec = new GCMParameterSpec(96, ivBytes);
                cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmSpec);
    //          cipher.updateAAD(encrypted, ivBytes.length, cipher.getBlockSize());
                byte[] decrypted = cipher.doFinal(encrypted, cipher.getBlockSize(), encrypted.length - cipher.getBlockSize());
    //          byte[] decrypted = cipher.doFinal(encrypted, cipher.getBlockSize()*2, encrypted.length - cipher.getBlockSize()*2);
                String decryptedString = new String(decrypted, "UTF-8");
                return decryptedString;
            } catch (NoSuchAlgorithmException | NoSuchPaddingException | UnsupportedEncodingException | InvalidKeyException | 
                    InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
                Logger.error(Utils.class, "decrypt()", "Could not decrypt string: " + e.getMessage());
                return null;
            }
        }
    

    Here is an example:

        String s = "This is a test.";
        String enc = Utils.encrypt(s);
        System.out.println(enc);
        // fQHfYjbD+xAuN5XzH2ojk/EWNeKXUrKRSfx8LU+5dpuKkM/pueCMBjKCZw==
        String dec = Utils.decrypt(enc);
        System.out.println(dec);
        // This is a test.
    
    0 讨论(0)
  • 2020-11-22 10:28

    Here's my implementation from meta64.com as a Spring Singleton. If you want to create a ciper instance for each call that would work also, and then you could remove the 'synchronized' calls, but beware 'cipher' is not thread-safe.

    import java.security.Key;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    import javax.xml.bind.DatatypeConverter;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Component;
    
    @Component
    @Scope("singleton")
    public class Encryptor {
    
        @Value("${aeskey}")
        private String keyStr;
    
        private Key aesKey = null;
        private Cipher cipher = null;
    
        synchronized private void init() throws Exception {
            if (keyStr == null || keyStr.length() != 16) {
                throw new Exception("bad aes key configured");
            }
            if (aesKey == null) {
                aesKey = new SecretKeySpec(keyStr.getBytes(), "AES");
                cipher = Cipher.getInstance("AES");
            }
        }
    
        synchronized public String encrypt(String text) throws Exception {
            init();
            cipher.init(Cipher.ENCRYPT_MODE, aesKey);
            return toHexString(cipher.doFinal(text.getBytes()));
        }
    
        synchronized public String decrypt(String text) throws Exception {
            init();
            cipher.init(Cipher.DECRYPT_MODE, aesKey);
            return new String(cipher.doFinal(toByteArray(text)));
        }
    
        public static String toHexString(byte[] array) {
            return DatatypeConverter.printHexBinary(array);
        }
    
        public static byte[] toByteArray(String s) {
            return DatatypeConverter.parseHexBinary(s);
        }
    
        /*
         * DO NOT DELETE
         * 
         * Use this commented code if you don't like using DatatypeConverter dependency
         */
        // public static String toHexStringOld(byte[] bytes) {
        // StringBuilder sb = new StringBuilder();
        // for (byte b : bytes) {
        // sb.append(String.format("%02X", b));
        // }
        // return sb.toString();
        // }
        //
        // public static byte[] toByteArrayOld(String s) {
        // int len = s.length();
        // byte[] data = new byte[len / 2];
        // for (int i = 0; i < len; i += 2) {
        // data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i +
        // 1), 16));
        // }
        // return data;
        // }
    }
    
    0 讨论(0)
  • 2020-11-22 10:28

    I would consider using something like https://www.bouncycastle.org/ It is a prebuilt library that allows you to encrypt whatever you like with a number of different Ciphers I understand that you only want to protect from snooping, but if you really want to protect the information, using Base64 won't actually protect you.

    0 讨论(0)
提交回复
热议问题