如何在cipher.doFinal方法中修复'Decryption Process'



>要求:

    使用
  • AES 加密(使用 GCMParameterSpec 和 nonce(加密字符串。
  • 将随机数附加到加密字符串,以便稍后使用它进行解密。
  • 通过提取随机数和要解密的字符串来解密字符串。

我已经编写了代码来根据需要加密和解密字符串,但我面临"解密标签不匹配时出错!

有人可以帮我确定问题吗?谢谢!

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AES {
    private static SecretKeySpec secretKey;
    private static byte[] key;
    private static final String ENCODING_TYPE = "UTF-8";
    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION_VALUE = "AES/GCM/NoPadding";
    public static void setKey(String myKey, String hashingType) {
        MessageDigest sha = null;
        try {
            key = myKey.getBytes(ENCODING_TYPE);
            sha = MessageDigest.getInstance(hashingType);
            key = sha.digest(key);
            key = Arrays.copyOf(key, 16);
            secretKey = new SecretKeySpec(key, ALGORITHM);
        } catch (NoSuchAlgorithmException e) {
            System.out.println("NoSuchAlgorithmException "+e.getMessage());
        } catch (UnsupportedEncodingException e) {
            System.out.println("UnsupportedEncodingException "+e.getMessage());
        } catch (Exception e) {
            System.out.println("Exception Occured! "+e.getMessage());
        }
    }
    public static String encrypt(String strToEncrypt, String secret, String hashingType) {
        String encryptedString = null;
        try {
            byte[] nonce = new byte[12];
            setKey(secret,hashingType);
            SecureRandom random = SecureRandom.getInstanceStrong();
            random.nextBytes(nonce);
            final Cipher encryptCipher = Cipher.getInstance(TRANSFORMATION_VALUE);
            encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(16 * 8, nonce));
            byte[] cipheredString = encryptCipher.doFinal(strToEncrypt.getBytes());
            ByteBuffer byteBuffer = ByteBuffer.allocate(nonce.length + cipheredString.length);
            byteBuffer.put(nonce);
            byteBuffer.put(cipheredString);
            encryptedString = Base64.getEncoder().encodeToString(byteBuffer.array());       //Encoding the ByteArrayOutputStream result object to Base64 format
        } catch (NoSuchAlgorithmException e) {
            System.out.println("NoSuchAlgorithmException "+e.getMessage());
        } catch (Exception e) {
            System.out.println("Error while encrypting "+e.getMessage());
        }
        return encryptedString;
    }
    public static String decrypt(String strToDecrypt, String secret, String hashingType) {
        String decryptedString = null;
        try {
            byte[] nonce = new byte[12];
            setKey(secret,hashingType);
            final Cipher decryptCipher = Cipher.getInstance(TRANSFORMATION_VALUE);
            ByteBuffer byteBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(strToDecrypt));
            byteBuffer.get(nonce);
            byte[] cipheredString = new byte[byteBuffer.remaining()];
            byteBuffer.get(cipheredString);
            decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(16 * 8, nonce));
            decryptedString = new String(decryptCipher.doFinal(cipheredString));
        } catch (Exception e) {
            System.out.println("Error while decrypting "+e.getMessage());
        }
        return decryptedString;
    }
}

    public class TestAESEncrypt {
        public static void main(String[] args) {
            final String secretKey = "NEWTEST@Key123";
            String originalString = "Gamer_123.aa01@gmail.com";
            String encryptedString = AESEncryption.encrypt(originalString, secretKey, "SHA-256");
            System.out.println("String to Encrypt : "+originalString);
            System.out.println("Encrypted String : "+encryptedString);
        }
    }

    public class TestAESDecryption {
        public static void main(String[] args) {
            final String secretKey = "NEWTEST@Key123";
            String encryptedData = "ey4E+5zNPx4WLx5q0Srf7d1TN/sAzsdYuVmnihXQoA/yoYoxAO/ygrtuh+Zr9rZQ"; //Paste the encrypted string here
            String decryptedString = AESEncryption.decrypt(encryptedData, secretKey, "SHA-256") ;
            System.out.println("Encrypted String : "+encryptedData);
            System.out.println("Decrypted String: "+decryptedString);
        }
    }

永远不会起作用:

encryptedString = new String(cipher.doFinal(strToEncrypt.getBytes()));  //Creating a ciphered string
encryptedString += new String(nonce); //Appending nonce to the encrypted string
encryptedString = new String(Base64.getEncoder().encode(encryptedString.getBytes()));   //Encoding ciphered string to Base64 format

一旦您尝试将原始字节转换为字符串,您可能已经损坏了数据。之后对它进行 Base64 编码不会拯救你。相反,您必须执行以下操作:

ByteArrayOutputStream result = new ByteArrayOutputStream();
result.write(nonce);
result.write(cipher.doFinal(strToEncrypt.getBytes()));
String encryptedString = Base64.getEncoder().encodeToString(result.toByteArray());

另外,我注意到你的随机数只有 8 个字节。这可能太短了,你应该把它变成 12 个字节。

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AES {
    private static SecretKeySpec secretKey;
    private static byte[] key;
    private static final String ENCODING_TYPE = "UTF-8";
    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION_VALUE = "AES/GCM/NoPadding";
    public static void setKey(String myKey, String hashingType) {
        MessageDigest sha = null;
        try {
            key = myKey.getBytes(ENCODING_TYPE);
            sha = MessageDigest.getInstance(hashingType);
            key = sha.digest(key);
            key = Arrays.copyOf(key, 16);
            secretKey = new SecretKeySpec(key, ALGORITHM);
        } catch (NoSuchAlgorithmException e) {
            System.out.println("NoSuchAlgorithmException "+e.getMessage());
        } catch (UnsupportedEncodingException e) {
            System.out.println("UnsupportedEncodingException "+e.getMessage());
        } catch (Exception e) {
            System.out.println("Exception Occured! "+e.getMessage());
        }
    }
    public static String encrypt(String strToEncrypt, String secret, String hashingType) {
        String encryptedString = null;
        try {
            byte[] nonce = new byte[12];
            setKey(secret,hashingType);
            SecureRandom random = SecureRandom.getInstanceStrong();
            random.nextBytes(nonce);
            final Cipher encryptCipher = Cipher.getInstance(TRANSFORMATION_VALUE);
            encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(16 * 8, nonce));
            byte[] cipheredString = encryptCipher.doFinal(strToEncrypt.getBytes());
            ByteBuffer byteBuffer = ByteBuffer.allocate(nonce.length + cipheredString.length);
            byteBuffer.put(nonce);
            byteBuffer.put(cipheredString);
            encryptedString = Base64.getEncoder().encodeToString(byteBuffer.array());       //Encoding the ByteArrayOutputStream result object to Base64 format
        } catch (NoSuchAlgorithmException e) {
            System.out.println("NoSuchAlgorithmException "+e.getMessage());
        } catch (Exception e) {
            System.out.println("Error while encrypting "+e.getMessage());
        }
        return encryptedString;
    }
    public static String decrypt(String strToDecrypt, String secret, String hashingType) {
        String decryptedString = null;
        try {
            byte[] nonce = new byte[12];
            setKey(secret,hashingType);
            final Cipher decryptCipher = Cipher.getInstance(TRANSFORMATION_VALUE);
            ByteBuffer byteBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(strToDecrypt));
            byteBuffer.get(nonce);
            byte[] cipheredString = new byte[byteBuffer.remaining()];
            byteBuffer.get(cipheredString);
            decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(16 * 8, nonce));
            decryptedString = new String(decryptCipher.doFinal(cipheredString));
        } catch (Exception e) {
            System.out.println("Error while decrypting "+e.getMessage());
        }
        return decryptedString;
    }
}

最新更新