How to encrypt String in Java

后端 未结 16 1427
梦毁少年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: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.
    

提交回复
热议问题