Надувной замок дает неизвестный хэш-алгоритм

Я пытаюсь использовать надувной замок для DTLS Handshake,
Я сгенерировал ключ по этой ссылке. Я работаю, расширяя DefaultTlsClient. Может генерировать пакет client_hello. Но когда приходит пакет server_hello, он дает org.bouncycastle.crypto.tls.TlsFatalAlert: internal_error(80) Вызванный: java.lang.IllegalArgumentException: unknown HashAlgorithm, Кто-нибудь может дать намек?

Обновить:
Из Wireshark: в запросе на сертификат есть 9 алгоритмов хэширования подписи. Один из них является rsa_pss_sha256(0x0804), в public static Digest createHash(short hashAlgorithm) функция в TlsUtils.java для этого нет соответствия. Вот почему он дает неизвестный алгоритм хеширования. Что это значит? Используя Bouncy Castle, возможно ли установить DTLS с этим сервером?

Вот код для загрузки хранилища ключей:

    public static void initKeyStore() {
    char password[] = "bbtone".toCharArray();
    if( !isKeystoreLoaded) {
     try {
        FileInputStream fis = new FileInputStream("bbtone");
        KeyMgmt key = new KeyMgmt();
        key.open(fis, password);
        fis.close();
        crt = key.getCRT("bbtone").getEncoded();
        fingerprintSHA256 = KeyMgmt.fingerprintSHA256(crt);
        ArrayList<byte[]> chain = new ArrayList<byte[]>();
        chain.add(crt);
        java.security.cert.Certificate root = key.getCRT("root");
        if (root != null) {
          chain.add(root.getEncoded());
        }
        privateKey = key.getKEY("bbtone", password).getEncoded();
        initDTLS(chain, privateKey, false);

        isKeystoreLoaded = true;
      } catch(FileNotFoundException e) {
          e.printStackTrace();
      } catch(Exception e) {
          e.printStackTrace();
      }
    }
}

Генерация закрытого ключа и сертификата:

      public static boolean initDTLS(java.util.List<byte []> certChain, byte privateKey[], boolean pkRSA) {
    try {
      org.bouncycastle.asn1.x509.Certificate x509certs[] = new org.bouncycastle.asn1.x509.Certificate[certChain.size()];
      for (int i = 0; i < certChain.size(); ++i) {
        x509certs[i] = org.bouncycastle.asn1.x509.Certificate.getInstance(certChain.get(i));
      }
      dtlsCertChain = new org.bouncycastle.crypto.tls.Certificate(x509certs);
      if (pkRSA) {
        RSAPrivateKey rsa = RSAPrivateKey.getInstance(privateKey);
        dtlsPrivateKey = new RSAPrivateCrtKeyParameters(rsa.getModulus(), rsa.getPublicExponent(),
                rsa.getPrivateExponent(), rsa.getPrime1(), rsa.getPrime2(), rsa.getExponent1(),
                rsa.getExponent2(), rsa.getCoefficient());
            } else {
              dtlsPrivateKey = PrivateKeyFactory.createKey(privateKey);
            }
      return true;
    } catch (Exception e) {
      return false;
    }
  }

Запуск DTLS рукопожатия:

  public void startDTLS() {

        socket.connect(recvPacket.getAddress(), recvPacket.getPort());
        try {
            dtlsClient = new DTLSClientProtocol(new SecureRandom());
          } catch (Exception e) {
            e.printStackTrace();
            dtlsClient = null;
            return;
          }
        tlsClient = new DefaultTlsClient2() {
            protected TlsSession session;
            public TlsSession getSessionToResume()
            {
              return this.session;
            }

            public ProtocolVersion getClientVersion() {
              return ProtocolVersion.DTLSv12;
            }

            public ProtocolVersion getMinimumVersion() {
              return ProtocolVersion.DTLSv10;
            }

            public Hashtable getClientExtensions() throws IOException {
              //see : http://bouncy-castle.1462172.n4.nabble.com/DTLS-SRTP-with-bouncycastle-1-49-td4656286.html
              logger.debug("Extending getClientExtensions\n");
              Hashtable table = super.getClientExtensions();
              if (table == null) table = new Hashtable();
              //adding the protection profiles

              int[] protectionProfiles = {
                SRTPProtectionProfile.SRTP_AES128_CM_HMAC_SHA1_80  //this is the only one supported for now
  //             SRTPProtectionProfile.SRTP_AES128_CM_HMAC_SHA1_32
  //              SRTPProtectionProfile.SRTP_NULL_HMAC_SHA1_32
  //              SRTPProtectionProfile.SRTP_NULL_HMAC_SHA1_80
              };
              byte mki[] = new byte[0];  //do not use mki
              UseSRTPData srtpData = new UseSRTPData(protectionProfiles, mki);
              TlsSRTPUtils.addUseSRTPExtension(table, srtpData);
              return table;
            }

            public TlsAuthentication getAuthentication() throws IOException {
              return new TlsAuthentication() {
                public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate)
                    throws IOException
                {
                  //info only
                }

                public TlsCredentials getClientCredentials(CertificateRequest certificateRequest)
                    throws IOException
                {
                  short[] certificateTypes = certificateRequest.getCertificateTypes();
                  if (certificateTypes == null) return null;
                  boolean ok = false;
                  for(int a=0;a<certificateTypes.length;a++) {
                    if (certificateTypes[a] == ClientCertificateType.rsa_sign) {
                      ok = true;
                      break;
                    }
                  }
                  if (!ok) return null;

                  SignatureAndHashAlgorithm signatureAndHashAlgorithm = null;
                  Vector sigAlgs = certificateRequest.getSupportedSignatureAlgorithms();
                  if (sigAlgs != null)
                  {
                    for (int i = 0; i < sigAlgs.size(); ++i)
                    {
                      SignatureAndHashAlgorithm sigAlg = (SignatureAndHashAlgorithm) sigAlgs.elementAt(i);
                      if (sigAlg.getSignature() == SignatureAlgorithm.rsa)
                      {
                        signatureAndHashAlgorithm = sigAlg;
                        break;
                      }
                    }

                    if (signatureAndHashAlgorithm == null)
                    {
                      return null;
                    }
                  }

                  return new DefaultTlsSignerCredentials(context, dtlsCertChain, dtlsPrivateKey, signatureAndHashAlgorithm);
                }
              };
            }
            public void notifyHandshakeComplete() throws IOException
            {
              logger.debug("SRTPChannel:DTLS:Client:Handshake complete");
              super.notifyHandshakeComplete();

              TlsSession newSession = context.getResumableSession();
              if (newSession != null)
              {
                this.session = newSession;
              }
              getKeys();
            }
          };  
          try {
              logger.debug("SRTPChannel:connecting to DTLS server");
              dtlsTransport = dtlsClient.connect(tlsClient, new UDPTransport(socket, 1500 - 20 - 8));
           } catch (Exception e) {
              e.printStackTrace();
           }
    }

Ошибка:

    org.bouncycastle.crypto.tls.TlsFatalAlert: internal_error(80)
    at org.bouncycastle.crypto.tls.DTLSClientProtocol.connect(DTLSClientProtocol.java:75)
    at processor.ClientMediaHandler.startDTLS(ClientMediaHandler.java:459)
    at processor.ClientMediaHandler.run(ClientMediaHandler.java:538)
Caused by: java.lang.IllegalArgumentException: unknown HashAlgorithm
    at org.bouncycastle.crypto.tls.TlsUtils.createHash(TlsUtils.java:1184)
    at org.bouncycastle.crypto.tls.DeferredHash.checkTrackingHash(DeferredHash.java:203)
    at org.bouncycastle.crypto.tls.DeferredHash.trackHashAlgorithm(DeferredHash.java:68)
    at org.bouncycastle.crypto.tls.TlsUtils.trackHashAlgorithms(TlsUtils.java:1358)
    at org.bouncycastle.crypto.tls.DTLSClientProtocol.clientHandshake(DTLSClientProtocol.java:241)
    at org.bouncycastle.crypto.tls.DTLSClientProtocol.connect(DTLSClientProtocol.java:60)
    ... 2 more

2 ответа

Решение

Я решил проблему с помощью DTLS1.0, Теперь он может закончить рукопожатие.

Я заменил

public ProtocolVersion getClientVersion() {
  return ProtocolVersion.DTLSv12;
}

со следующим кодом:

public ProtocolVersion getClientVersion() {
  return ProtocolVersion.DTLSv10;
}

@Rashed, понижение версии TLS - не лучший выбор. Уже есть комментарий от @bbaldino, но я думаю, что его следует добавить в качестве ответа - в версии 1.60 надувного замка есть ошибка. Вместо того, чтобы понижать TLS, вы должны обновить надувной замок как минимум до 1.61.

https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on

Другие вопросы по тегам