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

TLS 1.2奇怪的密码套件

潘佐
2023-03-14

我正在开发一个java应用程序,它将实现TLS协议。因为我最近开始实施它。在开发类型握手的记录协议实现时,我从google chrome和mozilla firefox获得了奇怪的密码套件。正如本文所述,在握手协议中有类型、握手长度、版本、随机、会话id长度、会话id、密码套件长度、密码套件。。。。。。。

我得到的所有字段都是正确的(在密码套件之前),但在密码套件上,我从google chrome和firefox得到了奇怪的值。

这是我的代码,它接受端口4040上的连接。

   package server;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
import java.security.KeyStore;
import java.security.SecureRandom;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

public class Server extends ServerSocket {
    public Server() throws IOException {
        super();
        // TODO Auto-generated constructor stub
    }
    public static void main(String args[]) 
    {
        System.setProperty("java.net.ssl.trustStore", "mam.store");
        System.setProperty("java.net.ssl.keyStorePassword", "mamoon");
        try {
            /*KeyStore ks  = KeyStore.getInstance("JKS");
            InputStream in = new FileInputStream("/Users/Ahmed/Desktop/mam.store");
            ks.load(in, "mamoon".toCharArray());
            in.close();
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(ks,"mamoon".toCharArray());
            TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
            tmf.init(ks);
            SSLContext con = SSLContext.getInstance("TLSv1.2");
            con.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

            SSLServerSocket socket = (SSLServerSocket)con.getServerSocketFactory().createServerSocket(4040);
            */
            ServerSocket socket = new ServerSocket(4040);
            System.out.println("Server is up.");

            Socket s = socket.accept();
            PrintWriter w = new PrintWriter(s.getOutputStream());
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream(),"ISO-8859-1"));
            String line;
            String packet = "";
            int l=0;
            while((line = br.readLine()) != null)
            {
                packet += line;
                System.out.println(line.length());
                if(packet.length() >= 100)
                {
                for(char c:packet.toCharArray())
                    System.out.print((int)c + "   ");
                System.out.println();
                new TLS(packet);
                break;
                }
            }
            System.out.println(l);
            //w.write("<html><body>hello world</body> </html>");
            //s.close();
            socket.close();

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

这是解码TLS数据包的类。

package server;

import java.math.BigInteger;
import java.nio.ByteBuffer;

public class TLS {
    String start = (char)22 + "" + (char)3;
    float version;
    int packetLength,handshakeLength,sessionIdLength;
    String random = "",sessionId = "";
    String message;
    String packetType,encryption;
    int cipherSuitsLength;
    int cipherSuitesId[];

    TLS(String packet) throws Exception
    {
        if(packet.startsWith(start))
        {
            version = Float.parseFloat((int)packet.charAt(1) + "."+(int)packet.charAt(2));
            packetLength = new BigInteger(new byte[]{(byte)packet.charAt(3),(byte)packet.charAt(4)}).intValue();
            System.out.println(packetLength);
                    //(byte)packet.charAt(3) << 8 | ((byte)packet.charAt(4) & 0xFF);
            if((int)packet.charAt(5) == 1)
                packetType = "Client Hello";
            else if((int)packet.charAt(5) == 2)
                packetType = "Server Hello";
            else if((int)packet.charAt(5) == 11)
                packetType = "Certificate";
            else if((int)packet.charAt(5) == 12)
                packetType = "Server Key Exchange";
            else if((int)packet.charAt(5) == 13)
                packetType = "Certificate Request";
            else if((int)packet.charAt(5) == 14)
                packetType = "Server Done";
            else if((int)packet.charAt(5) == 15)
                packetType = "Certificate Verify";
            else if((int)packet.charAt(5) == 16)
                packetType = "Client Key Exchange";
            else if((int)packet.charAt(5) == 20)
                packetType = "Finished";
            handshakeLength = new BigInteger(new byte[] {(byte)packet.charAt(6) , (byte)packet.charAt(7), (byte)packet.charAt(8)}).intValue(); 
                    //(byte)packet.charAt(7) << 16 | ((byte)packet.charAt(8) << 8 & 0xFF) | ((byte));
            System.out.println(handshakeLength);
            version = Float.parseFloat((int)packet.charAt(9) + "."+(int)packet.charAt(10));
            System.out.println(version);
            for(int a=11;a<11+32;a++)
            {   random += packet.charAt(a);
            System.out.println((int)packet.charAt(a));
            }
            System.out.println(random.length());
            sessionIdLength = (int)packet.charAt(43);
            System.out.println(sessionIdLength);
            int c = 44+sessionIdLength;
            for(int a=44;a<44+sessionIdLength;a++)
            {
                sessionId += packet.charAt(a);
            }
            System.out.println(sessionId);
            cipherSuitsLength = new BigInteger(new byte[] {(byte)packet.charAt(c),(byte) packet.charAt(c+1)}).intValue();
            System.out.println(cipherSuitsLength);
            cipherSuitesId = new int[cipherSuitsLength/2];
            c+=2;
            for(int a=0;a<cipherSuitesId.length;a++)
            {
                cipherSuitesId[a] = new BigInteger(new byte[]{(byte)packet.charAt(c),(byte)packet.charAt(c+1)}).intValue();
                c+=2;
                System.out.println(cipherSuitesId[a]);
            }
        }
        else
            throw new Exception("Not a TLS packet.");
    }
    public void processTLS(String packet)
    {

    }
}

我的代码的输出是

Server is up.
51
19
14
61
22   3   1   0   168   1   0   0   164   3   3   57   220   109   126   106   16   106   75   232   65   206   177   89   90   5   241   76   167   135   150   97   51   67   213   33   60   209   73   137   119   119   80   0   0   30   192   43   192   47   192   192   9   192   19   192   20   192   7   192   17   0   51   0   57   0   47   0   53   0   0   5   0   4   1   0   0   93   255   1   0   1   0   0   0   8   0   6   0   23   0   24   0   25   0   11   0   2   1   0   0   35   0   0   51   116   0   0   0   16   0   23   0   21   2   104   50   8   115   112   100   121   47   51   46   49   8   104   116   116   112   47   49   46   49   0   5   0   5   1   0   0   0   0   0   
168
164
3.3
57
220
109
126
106
16
106
75
232
65
206
177
89
90
5
241
76
167
135
150
97
51
67
213
33
60
209
73
137
119
119
80
32
0

30
-16341
-16337
-16192
2496
5056
5312
1984
4352
13056
14592
12032
13568
5
4
256
0

如您所见,密码套件长度为0 30,这意味着收到了15个密码套件。但我确信没有像19243这样的密码套件id。请帮帮我。

共有3个答案

景翰音
2023-03-14

是的,还有另一个问题,第三个密码套装id是192 192,但没有这样的密码套装存在。这是因为br.readLine()声明。它将跳过字符10并将其视为换行符,但它实际上是信息。使用字节数组读取数据是正确的方法。

DataInputStream s = new DataInputStream(socket.getInputStream());
byte data[] = new byte[s.available()];
s.readFully(data);

此实现将给出实际数据。

能烨华
2023-03-14

192 43是TLS_ECDHE_ECDSA_和_AES_128_GCM_SHA256的id。

Wireshark数据包捕获。TLS 1.2客户端你好数据包。

下面是密码套件ID的完整列表。

梁昊天
2023-03-14

您正在解析每个数据包,就好像它包含密码套件一样。他们没有。

您一开始也完全走错了路。TLS记录是二进制的,String不是二进制数据的容器。

这样的代码结构,你真的永远不会有任何进展。在你领先的时候退出,或者看看真正的实现是如何编码的。绝对不是这样的。

 类似资料:
  • DHE-RSA-AES128-GCM-SHA256; ECDHE-RSA-AES128-GCM-SHA256;-->这管用 DHE-RSA-AES256-GCM-SHA384; 是我的配置有问题还是密码不受支持。

  • 问题内容: 所有! 我在LinkedBlockingQueue中发现了奇怪的代码: 谁能解释为什么我们需要局部变量h?它对GC有什么帮助? 问题答案: 为了更好地了解发生了什么,让我们看看执行代码后列表的样子。首先考虑一个初始列表: 然后指向和指向: 然后指向和指向: 现在,实际上我们知道只有一个指向第一个元素的活动引用,它本身就是(),并且我们还知道GC收集的对象不再具有活动引用,所以当方法结束

  • 问题内容: 我使用jsoup从不同页面的html源代码中提取了一些信息。它们大多数是UTF-8编码的。其中之一是使用ISO-8859-1编码的,这会导致一个奇怪的错误(在我看来)。 包含错误的页面是:http : //www.gudi.ch/armbanduhr- metall- wasserdicht-1280x960-megapixels-p-560.html 我用以下代码阅读了所需的Stri

  • 我在写需要加密和解密文件的应用程序。我的问题是解密比加密慢5倍。我已经删除了所有的文件读/写操作,并且只对加密进程进行了基准测试。结果非常令人惊讶: 使用(是javax.crypto.cipher的实例)加密1.5MB字节数组 我很惊讶,因为我知道AES解密和加密是对称的过程,在加密和解密速度上应该没有区别。 我使用密码,密钥为256位。

  • 我有以下代码来解析一个JSON文件: 要处理以下JSON文件: 如果我执行此代码,我将收到以下错误: 所以我开始一步一步地调试应用程序,看看part processing()中的哪个代码部分抛出了这个异常。令人惊讶的是,那里的所有代码都正常执行:没有抛出异常,也没有返回结果I except。 更让我惊讶的是,当我稍微改变第一种方法的代码时,它可以在不产生异常的情况下工作。 我不知道println方

  • 我对证书知之甚少。 需要添加码头证书(v.9.4.11),这是申请的一部分。 用自签名试试——都可以。但是现在,需要用组织官方证书做。 管理员给我2个文件-。cer和。p7b。申请文件显示,足够的命令如下: keyool-导入-信任Cacerts-别名mydome-filemydomain.crt-keystorekeystore.jks 我将尝试使用。而不是。crt。密钥存储已创建、配置jett