当前位置: 首页 > 知识库问答 >
问题:

发送方和接收方消息字节、内容大小不匹配和javax.crypto.aeadBadTagException:AES-GCM模式下的标记不匹配

钱京
2023-03-14
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
byte[] rec=receivePacket.getData();
String receivedData = new String(rec,0,receivePacket.getLength());
System.out.println(receivePacket.getLength());//18 bytes
System.out.println(receivedData.length);// 30 bytes(how???)
byte[] plainText = cipher.doFinal(cipherText);  

示例客户端:

class GCMClient
{
    // AES-GCM parameters
    public static final int AES_KEY_SIZE = 128; // in bits
    public static final int GCM_NONCE_LENGTH = 12; // in bytes
    public static final int GCM_TAG_LENGTH = 16; // in bytes
    public static void main(String args[]) throws Exception{        
        DatagramSocket clientSocket = new DatagramSocket();
        InetAddress IPAddress = InetAddress.getByName("192.168.1.8");
        byte[] sendData = new byte[1024];
        byte[] receiveData = new byte[1024];        
        byte[] input = "hi".getBytes(); //2 bytes 

        byte[] keyBytes ="qwertyuiopasdfgh".getBytes();
        SecretKey key = new SecretKeySpec(keyBytes, 0, keyBytes.length, "AES");       
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
        byte[] nonce = new byte[GCM_NONCE_LENGTH];
        nonce = "poiuytrewqlk".getBytes();;;        
        GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);
        cipher.init(Cipher.ENCRYPT_MODE, key, spec);
        byte[] aad =  "Whatever I like".getBytes();;
        cipher.updateAAD(aad);
        byte[] cipherText = cipher.doFinal(input); 
        System.out.println(cipherText.length+ "data sent!!!!!!! "); //18 bytes after encryption
        DatagramPacket sendPacket = new DatagramPacket(cipherText, cipherText.length, IPAddress, 9999);
        clientSocket.send(sendPacket);  
        clientSocket.close();     
   }
}

示例服务器:

class GCMServer
{
     // AES-GCM parameters
    public static final int AES_KEY_SIZE = 128; // in bits
    public static final int GCM_NONCE_LENGTH = 12; // in bytes
    public static final int GCM_TAG_LENGTH = 16; // in bytes

    public static void main(String args[]) throws Exception{ 
        try{
            DatagramSocket serverSocket = new DatagramSocket(9999,InetAddress.getByName("192.168.1.8"));
            byte[] receiveData = new byte[1024];
            byte[] sendData = new byte[1024];
            while(true){           
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                receivePacket.setData(new byte[4096]);  
                serverSocket.receive(receivePacket);
                byte[] rec=receivePacket.getData();
                String receivedData = new String(rec,0,receivePacket.getLength());          
                byte[] cipherText = receivedData.getBytes();

                System.out.println("received packet size before convert to bytes "+receivePacket.getLength());//it displays 18
                System.out.println("received packet size after convert to bytes "+cipherText.length);//it display 30 how???? it must be 18          


                byte[] keyBytes ="qwertyuiopasdfgh".getBytes();
                SecretKey key = new SecretKeySpec(keyBytes, 0, keyBytes.length, "AES");       
                Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
                byte[] nonce = new byte[GCM_NONCE_LENGTH];
                nonce = "poiuytrewqlk".getBytes();;;        
                GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);            
                byte[] aad = "Whatever I like".getBytes();;         
                cipher.init(Cipher.DECRYPT_MODE, key, spec);     
                cipher.updateAAD(aad);      
                byte[] plainText = cipher.doFinal(cipherText);      
                System.out.println("After decryption "+new String(plainText));
            }
        }catch(Exception e){
            System.out.println("Exception caught "+e);//got Exception caught javax.crypto.AEADBadTagException: Tag mismatch!
        }
     }
}

共有1个答案

娄森
2023-03-14

我不知道为什么字节内容大小不同,但是,当我使用以下代码时,它就解决了

 DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
    serverSocket.receive(receivePacket);
    byte[] rec=receivePacket.getData();
    byte[] cipherText=new byte[receivePacket.getLength()];
    System.arraycopy(rec, 0, cipherText, 0, receivePacket.getLength());

取而代之的是

DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
byte[] rec=receivePacket.getData();
String receivedData = new String(rec,0,receivePacket.getLength());

并解决了javax.crypto.AEADBadTagException:标记不匹配异常

 类似资料:
  • 我正在尝试在我的android应用程序中使用GCM服务。 为此,我使用Android留档从http://developer.android.com/guide/google/gcm/gcm.html 我用发送者id等创建了客户端注册过程,并在服务器端应用程序中使用注册id和发送者id发送消息。 当我通过Eclipse在手机中安装应用程序时,推送通知工作正常,因此我的发件人id是正确的。 然后,当我

  • 通常在服务器发送一些数据时发生Message事件。服务器发送到客户端的消息可以包括纯文本消息,二进制数据或图像。无论何时发送数据,都会触发函数。 此事件充当客户端对服务器的耳朵。每当服务器发送数据时,都会触发事件。 以下代码段描述了打开Web Socket协议的连接。 还需要考虑使用Web套接字可以传输哪些类型的数据。Web套接字协议支持文本和二进制数据。就Javascript而言,文本指的是字符

  • 我有1个活动和1个普通类,其中活动1接收消息,普通类发送消息。如何实施: 在活动一中。班 在Ordinary.class 如何发送空消息(1)的代码?

  • 我试图用ANTLR创建一个lexer/parser,它可以解析中间分散有标记的纯文本。这些标记由打开({)和关闭(})括号表示,它们表示可以计算为字符串的Java对象,然后在原始输入中替换该字符串,以创建排序的动态模板。 这里有一个例子:{player:name}向你问好!{player:name}应该被玩家的名字替换,并导致输出,即Mark say hi!为了那个叫马克的玩家。 现在我可以很好地

  • 我在angular 5中实现了一个模式,在.ts文件中使用以下代码进行密码验证。这样做的目的是支持至少八个字符,至少一个大写字母、一个小写字母、一位数字和一个特殊字符。请参阅:密码的Regex必须包含至少八个字符、至少一个数字以及大小写字母和特殊字符 我明白了,当我在密码文本框中输入一个字符串时,例如< code>Niladri1!然而,当我输入一个类似于< code>Nopasss123!!,它

  • 我正在计算非负p的Lp距离函数。除了p=0和p=∞ 内置的pow()函数可以很好地发挥作用。在学习结构模式匹配之前,我使用了字典和异常处理: 有些人不希望这里有例外。因此,我将该片段改写为以下内容: 为什么大小写inf不正确(Python v3.10.2)?