private static boolean isKeyValid()

in src/main/java/com/company/license/CheckLicense.java [160:193]


  private static boolean isKeyValid(String key) {
    String[] licenseParts = key.split("-");
    if (licenseParts.length !=  4) {
      return false; // invalid format
    }

    final String licenseId = licenseParts[0];
    final String licensePartBase64 = licenseParts[1];
    final String signatureBase64 = licenseParts[2];
    final String certBase64 = licenseParts[3];

    try {
      final Signature sig = Signature.getInstance("SHA1withRSA");
      // the last parameter of 'createCertificate()' set to 'false' switches off certificate expiration checks.
      // This might be the case if the key is at the same time a perpetual fallback license for older IDE versions.
      // Here it is only important that the key was signed with an authentic JetBrains certificate.
      sig.initVerify(createCertificate(
        Base64.getMimeDecoder().decode(certBase64.getBytes(StandardCharsets.UTF_8)), Collections.emptySet(), false
      ));
      final byte[] licenseBytes = Base64.getMimeDecoder().decode(licensePartBase64.getBytes(StandardCharsets.UTF_8));
      sig.update(licenseBytes);
      if (!sig.verify(Base64.getMimeDecoder().decode(signatureBase64.getBytes(StandardCharsets.UTF_8)))) {
        return false;
      }
      // Optional additional check: the licenseId corresponds to the licenseId encoded in the signed license data
      // The following is a 'least-effort' code. It would be more accurate to parse json and then find there the value of the attribute "licenseId"
      final String licenseData = new String(licenseBytes, StandardCharsets.UTF_8);
      return licenseData.contains("\"licenseId\":\"" + licenseId + "\"");
    }
    catch (Throwable e) {
      e.printStackTrace(); // For debug purposes only. Normally you will not want to print exception's trace to console
    }
    return false;
  }