IntelliJ IDEA 2025.3.1.1 记录

JetBrains IntelliJ IDEA 2025.3.1.1 记录

前置ja-netfilter 安装

参考:

ja-netfilter.jar 文件

Release 2025.3.0 · ja-netfilter/ja-netfilter - Gitee.com

scripts 和vmoptions 目录

zeng-zijie/ja-netfilter

config和plugins 目录

zpj80231/idea-set

注意项

要使用自生成的激活码则必须要配置power.conf 文件

参考:

ja-netfilter power插件原理 - MoYuno

激活码生成

需要将新的“生成power.conf ” 结果复制到ja-netfilter\config-jetbrains\power.conf或者ja-netfilter\config\power.conf (要根据ja-netfilter安装时的配置)

# https://github.com/just-ads/script/blob/main/idea/sign.py

import base64
import datetime
import os
from typing import Tuple

import json
#pip install pycryptodome
from Crypto.Hash import SHA256
from Crypto.Signature.pkcs1_15 import _EMSA_PKCS1_V1_5_ENCODE
from Crypto.Util.number import ceil_div

#pip install cryptography
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.x509.oid import NameOID

# 常量定义
ONE_DAY = datetime.timedelta(days=1)
TEN_YEARS = datetime.timedelta(days=3650)
CA_COMMON_NAME = "JetProfile CA"
CERT_COMMON_NAME = "IKUN"
KEY_SIZE = 4096
PUBLIC_EXPONENT = 65537


def generate_self_signed_certificate(
        cert_common_name: str = CERT_COMMON_NAME,
        key_size: int = KEY_SIZE,
        validity_days: int = 3650
) -> Tuple[rsa.RSAPrivateKey, x509.Certificate]:
    """
    生成自签名的CA证书

    Args:
        cert_common_name: 证书的通用名称
        key_size: RSA密钥大小
        validity_days: 证书有效期(天)

    Returns:
        私钥和证书的元组
    """
    print("\n=== 生成自签名CA证书 ===")
    today = datetime.datetime.today()
    not_valid_before = today - ONE_DAY
    not_valid_after = today + datetime.timedelta(days=validity_days)

    # 生成RSA密钥对
    private_key = rsa.generate_private_key(
        public_exponent=PUBLIC_EXPONENT,
        key_size=key_size,
        backend=default_backend()
    )
    public_key = private_key.public_key()

    # 构建证书
    builder = x509.CertificateBuilder()
    builder = builder.subject_name(x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME, cert_common_name),
    ]))
    builder = builder.issuer_name(x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME, 'JetProfile CA'),
    ]))
    builder = builder.not_valid_before(not_valid_before)
    builder = builder.not_valid_after(not_valid_after)
    builder = builder.serial_number(x509.random_serial_number())
    builder = builder.public_key(public_key)

    # 签名证书
    certificate = builder.sign(
        private_key=private_key,
        algorithm=hashes.SHA256(),
        backend=default_backend()
    )

    save_key_and_certificate(private_key, certificate)

    return private_key, certificate


def save_key_and_certificate(
        private_key: rsa.RSAPrivateKey,
        certificate: x509.Certificate,
        key_filename: str = "ca.key",
        cert_filename: str = "ca.crt"
) -> None:
    """
    保存私钥和证书到文件

    Args:
        private_key: RSA私钥
        certificate: X.509证书
        key_filename: 私钥文件名
        cert_filename: 证书文件名
    """
    # 序列化私钥
    private_bytes = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    )

    # 序列化证书
    public_bytes = certificate.public_bytes(
        encoding=serialization.Encoding.PEM
    )

    # 写入文件
    with open(key_filename, "wb") as f:
        f.write(private_bytes)
    with open(cert_filename, "wb") as f:
        f.write(public_bytes)

    print("✓ 证书已生成并保存到 ca.key 和 ca.crt")


def load_certificate_from_file() -> Tuple[rsa.RSAPrivateKey, x509.Certificate]:
    """
    从文件加载证书,支持PEM和DER格式
    Returns:
        X.509证书对象
    Raises:
        ValueError: 如果证书格式无效
    """

    print('\n======加载证书======')

    with open('ca.crt', "rb") as f:
        cert_data = f.read()

    with open('ca.key', "rb") as f:
        key_data = f.read()

    try:
        certificate = x509.load_pem_x509_certificate(cert_data, default_backend())
        private_key = serialization.load_pem_private_key(key_data, password=None)
        return private_key, certificate
    except Exception:
        try:
            certificate = x509.load_der_x509_certificate(cert_data, default_backend())
            private_key = serialization.load_der_private_key(key_data, password=None)
            return private_key, certificate
        except Exception as e:
            raise ValueError(f"无法加载证书文件: {e}")


def create_license_signature(license_data: dict, private_key: rsa.RSAPrivateKey) -> str:
    """
    创建许可证签名

    Args:
        license_data: 许可证数据
        private_key: 私钥
    Returns:
        完整的许可证字符串
    """
    try:
        license_id = license_data.get('licenseId')
        license_bytes = json.dumps(license_data).encode('utf-8')
        signature = private_key.sign(
            license_bytes,
            padding.PKCS1v15(),
            hashes.SHA1()
        )
        # Base64编码
        license_part_base64 = base64.b64encode(license_bytes).decode('utf-8')
        signature_base64 = base64.b64encode(signature).decode('utf-8')

        return f"{license_id}-{license_part_base64}-{signature_base64}"

    except Exception as e:
        print(f"创建许可证签名时出错: {e}")
        raise


def verify_license_signature(license_string: str, cert_base64: str) -> bool:
    """
    验证许可证签名

    Args:
        license_string: 许可证字符串
        cert_base64: Base64编码的证书(DER格式)

    Returns:
        签名是否有效
    """
    try:
        # 解析许可证字符串
        parts = license_string.split('-')
        if len(parts) < 3:
            raise ValueError("无效的许可证格式")

        license_part_base64 = parts[1]
        signature_base64 = parts[2]

        # 解码许可证数据
        license_data = base64.b64decode(license_part_base64).decode('utf-8')

        # 加载证书和公钥
        cert = x509.load_der_x509_certificate(base64.b64decode(cert_base64))
        public_key = cert.public_key()

        # 验证签名
        public_key.verify(
            base64.b64decode(signature_base64),
            license_data.encode('utf-8'),
            padding=padding.PKCS1v15(),
            algorithm=hashes.SHA1(),
        )

        return True

    except Exception as e:
        print(f"验证许可证签名时出错: {e}")
        return False
# https://github.com/JetBrains/marketplace-makemecoffee-plugin/blob/master/src/main/java/com/company/license/CheckLicense.java
JB_ROOT_CERTS=[
    "-----BEGIN CERTIFICATE-----\n" +
      "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\n" +
      "-----END CERTIFICATE-----\n",
    "-----BEGIN CERTIFICATE-----\n" +
      "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\n" +
      "7tlDFnvaRnQukqSG+VqNWg==\n" +
      "-----END CERTIFICATE-----"]
def generate_power_conf(sign:int, result:int,outpath='power.conf'):
    cfgs=[]
    roots=x509.load_pem_x509_certificates(''.join(JB_ROOT_CERTS).encode())
    for cert in  roots:
        public_key = cert.public_key()
        pn=public_key.public_numbers()
        n=pn.n
        conf=f'EQUAL,{sign},{PUBLIC_EXPONENT},{n}->{result}'
        cfgs.append(conf)
    text='[Result]\n'+'\n'.join(cfgs)
    print(text)
    print('\n\n\n')
    # if os.path.exists(outpath):
    #     os.rename(outpath,outpath+'.bak')
    #     print(f'backup file:{outpath}==>{outpath}.bak')
    if not os.path.exists(outpath):
        with open(outpath, 'w', encoding='utf-8') as f:
            f.write(text)
            print(f"wirte to:",outpath)

def make_products(Date:str,codes:list[str]):
    out=[]
    for x in codes:
        d={
            "code": x,
            "fallbackDate": Date,
            "paidUpTo": Date,
            "extended": True
        }
        out.append(d)
    return out

def main():
    is_cert_exists = os.path.exists('ca.key') and os.path.exists('ca.crt')
    if is_cert_exists:
        private_key, cert = load_certificate_from_file()
    else:
        private_key, cert = generate_self_signed_certificate()

    # 打印证书信息
    print(f"\n证书主题: {cert.subject}")
    print(f"证书颁发者: {cert.issuer}")
    print(f"证书有效期: {cert.not_valid_before_utc} 到 {cert.not_valid_after_utc}")
    print(f"证书序列号: {cert.serial_number} \n")

    cert_base64 = base64.b64encode(cert.public_bytes(serialization.Encoding.DER)).decode('utf-8')

    public_key = cert.public_key()

    # 计算签名值
    sign = int.from_bytes(cert.signature, byteorder="big")
    print(f"证书签名值: {sign}")

    # 计算TBS证书的哈希
    mod_bits = public_key.key_size
    digest_cert = SHA256.new(cert.tbs_certificate_bytes)

    # 使用PKCS#1 v1.5编码
    r = int.from_bytes(
        _EMSA_PKCS1_V1_5_ENCODE(digest_cert, ceil_div(mod_bits, 8)),
        byteorder='big',
        signed=False
    )
    print(f"计算得到的签名值: {r}")

    print(f"\n=== 生成power.conf ===")

    generate_power_conf(sign, r)

    print("\n=== 创建许可证签名 ===")
    date = (datetime.datetime.today() + datetime.timedelta(5 * 365)).strftime("%Y-%m-%d")
    licenseId = base64.b32encode(os.urandom(10)).decode()[:10]
    licenseeName = 'IKUN'
    assigneeName = 'kunkun'
    # codes=["PCWMP","PRR","PDB","PSI","II", "PS", "AC", "DB", "RM", "WS", "RD", "CL", "PC", "GO", "DS", "DC", "DPN", "DM"]
    codes=["II","PCWMP","PSI"]

    license_data = {
        'licenseId': licenseId,
        'licenseeName': licenseeName,
        'licenseeType': 'PERSONAL',
        'assigneeName': assigneeName,
        'assigneeEmail': "",
        'licenseRestriction': "JetBrains",
        'checkConcurrentUse': False,
        "products": make_products(date,codes),
        # "metadata": "0120230102PPAA013009",
        "metadata": "0120230914PSAX000005",
        # "hash": "41472961/0:1563609451",
        "gracePeriodDays": 7,
        "autoProlongated": False,
        "isAutoProlongated": False,
        'trial': False,
        'aiAllowed': True
    }
    license_string = f'{create_license_signature(license_data, private_key)}-{cert_base64}'
    print(f"✓ 许可证签名已创建")
    print(license_string)

    print("\n=== 验证许可证签名 ===")
    if verify_license_signature(license_string, cert_base64):
        print("✓ 许可证签名验证成功")
    else:
        print("✗ 许可证签名验证失败")


if __name__ == "__main__":
    main()

自签名验证

def lic_test(lic:bytes):
    if isinstance(lic,str):
        lic=lic.encode()
    licenseId,licensePartBase64,sig_results,certBase64=lic.split(b'-')
    print('[-]licenseId:',licenseId)
    print('[-]sig_results:',sig_results)
    # print(parts)
    print('[-]license:',base64.standard_b64decode(licensePartBase64) )
    cert=x509.load_der_x509_certificate(base64.b64decode(certBase64))
    print('[-]cert:',cert)
    print('\t cert.serial_number:',cert.serial_number)
    print('\t cert.issuer:',cert.issuer)
    print('\t cert.subject:',cert.subject)
    public_key = cert.public_key()
    print(public_key.public_numbers())
    try:
        public_key.verify(
            base64.b64decode(sig_results),
            base64.b64decode(licensePartBase64),
            padding=padding.PKCS1v15(),
            algorithm=hashes.SHA1(),
        )
        print('[+]lic verify ok!')
    except:
        print('[!]lic verify error!')

'Ultimate' 功能需要许可证。(todo)

一段时间之后就会弹窗

'Ultimate' 功能需要许可证。

不知道哪个地方的校验,未解决,可能需要在url.conf添加项

断网使用0.0

ps

alt text

参考链接

Release 2025.3.0 · ja-netfilter/ja-netfilter - Gitee.com

zeng-zijie/ja-netfilter

zpj80231/idea-set

marketplace-makemecoffee-plugin

ja-netfilter破解某IDE原理分析及生成激活码 - 知乎

ja-netfilter power插件原理 - MoYuno

script/idea/sign.py at main · just-ads/script

posted @ 2026-01-11 19:05  DirWangK  阅读(1)  评论(0)    收藏  举报