跳转至

看透激活码

-javaagent:C:\Users\LYM\code\break_scripts\Jetbrains\ja-netfilter.jar=jetbrains
-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5050

Arrays.stream(configs).map(c->c.getProvider().getService("CertStore", "X509")).toList()

Files.write(Path.of("C:/Users/LYM/code/break_scripts/"), new ArrayList<>(((PKIXBuilderParameters) params).unmodTrustAnchors).get(0).getTrustedCert().getEncoded())


java.nio.file.Files.write(java.nio.file.Path.of("C:/Users/LYM/code/break_scripts/2022.3.3-33.crt"),getEncoded())

Arrays.toString(CertificateFactory.getInstance("X509").generateCertificate(new FileInputStream("C:/Users/LYM/code/break_scripts/license-XIZQAN09CR.crt")).getEncoded())


RSACore.parseMsg(signature, ((RSAPublicKeyImpl) key).getModulus())
l2cached.getOrDefault(x + "," + y + "," + z, null);
info.toString().contains("JetProfile CA")

JDK版本问题

  • SunCertPathBuilder#depthFirstSearchForward:JDK8和JBR17.0.10差不多,但是JBR17.0.6不一样
    • JDK8和JBR17.0.10
      • ForwardBuilder#verifyCert:trust不再verify,即便verify也不是签名的verify
      • PathComplete后,BasicChecker变成必须的了
        • 正是在BasicChecker执行userCert.verify(CACert.public)
  • RSASignature:JDK8和JBR17.0.6差不多,但是JBR17.0.10不一样
    • JBR17.0.10
      • 反过来了,MessageDigest(decrypted, padding(encodeSignature(digest)))
  • ja-netfilter

    • 不知道为什么,使用IDEA2022.3.3的JBR或者JDK17.0.2都不能触发ja-netfilter代理,JDK8就可以,但是IDEA2022.3.3是怎么被激活的呢?明明是JBR17.0.6
    • 但是不知道为什么,RemoteDebug IDEA2022.3.3(JBR17.0.6)却可以
  • 怪哉,无idea.key和plugin_PCWMP.license也可以运行2022.3

激活码

idea.key

  • license中的时间和证书中的时间不对应
  • 43B4A73YYJ
    • licenseeName=lan yu
    • license.paidUpTo=2017-02-25
    • user subject=CN=prod3y
    • certValidity: 2015.11.02-2018.11.01
    • fingerprint-sha1=e14efa20f0e96ba056c8d4417e68fbd588bae410
  • FDXL1Y2811
    • licenseeName=mao zedong
    • license.paidUpTo=2024-03-26
    • user subject=CN=prod2y-from-20221010
    • certValidity: 2022.10.11-2024.10.12
    • fingerprint-sha1=3bbe60ad7e0a57418be433db0286fdde6cf94dda
  • K384HW36OB
    • licenseeName=kiddy inseams
    • license.paidUpTo=2024-05-11
    • user subject=CN=prod2y-from-20221010
    • certValidity: 2022.10.11-2024.10.12
    • fingerprint-sha1=3bbe60ad7e0a57418be433db0286fdde6cf94dda
  • XIZQAN09CR
    • licenseeName=Benoit Menendez
    • license.paidUpTo=2025-08-01
    • user subject=CN=prod2y-from-20201019
    • certValidity: 2020.10.19-2022.10.21
    • fingerprint-sha1=e22bb88395f33a1cfbd70abaeb1c912c7d1a5160

plugin_PCWMP.license

  • Personal Code With Me Plugin的license
  • 和idea.key激活码不一样,可能在idea.key可以的,pcwmp就不行,也可能反过来

激活idea

  • 2024激活成功时,还顺便激活了pcwmp

  • 输入非法激活码时

    • 解码Base64:
      • LicenseJSON、 idea.key-256B、
      • crl文件、crl文件的用户证书prod2y-from-20201019、crl文件的256B、crl文件的CRL
      • idea-rootca( JetProfile CA),不知道那里来的
      • idea.key-cert
    • java.security.cert.CertPathBuilder#build:所有都验证成功
      • 即便
        • 是43B4A73YYJ(2015-2018)、K384HW36OB
        • 是sun.security.x509.X509CertImpl#checkValidity(java.util.Date)(只传入了证书的NoBefore)
    • 因此不是证书问题

激活失败错误信息注意

  • Key is invalid、License is valid till Mar 26, 2024
    • 在激活页面输入非法激活码错误
  • We could not validate your license FDXL1Y2811、This license K384HW36OB has been suspended.
    • 如果在激活后,迅速打开一个项目,短时间内不会怎么样
      • 然而点击help/register打开license管理页,就又会出现这样的错误
      • 或者过了一小段时间,自动弹出license管理页显示这个错误
      • 再次输入激活码,则立刻出现这个错误
    • 重新打开IDE,延迟一下页立刻报这个错误
  • This license K384HW36OB has been suspended.
    • 原因是激活码使用人数过多,关闭网络或者设置IDE的代理激活一下后重新联网即可
    • 这是合法key,license

使用ja-netfilter前

  • 对于最新的ide来说,过期的key一般都无法验证为合法
43B4A73YYJ FDXL1Y2811 K384HW36OB XIZQAN09CR
Key is invalid(非法key) 2022.2、2022.3、2024.1 2022.2、2022.3、2024.1
We could not validate your license FDXL1Y2811. 合法key,非法license 2022.2、2022.3
This license K384HW36OB has been suspended. 2022.2、2022.3、2024.1
License is valid till xxx(如Mar 26, 2024,过期非法key) 2024.1
成功

使用ja-netfilter后

43B4A73YYJ FDXL1Y2811 K384HW36OB XIZQAN09CR
Key is invalid(非法key) 2022.2、2022.3、2024.1
We could not validate your license FDXL1Y2811. 合法key,非法license
This license K384HW36OB has been suspended.
License is valid till xxx(如Mar 26, 2024,过期非法key) 2024.1
成功 2022.2、2022.3 2022.2、2022.3、2024.1 2022.2、2022.3、2024.1
### ja-netfilter作用
- 作用
- 非法key:有些√,有些仍然×(可能是key过期时间太早了)
- 过期key:×
- 合法key,非法license:√
- 功能
- 替换RSA解密参数,替换RSA解密结果
- 阻断URLConnection
- 阻断域名

合法key,非法license-->合法license

ja-netfilter

  • 拦截URL
    • GET
    • https://account.jetbrains.com/lservice/rpc/validateKey.action?buildDate=20221129&buildNumber=2022.3.3+Build+IU-223.8836.41&clientVersion=13&hostName=&licenseHash=41472961%2F0%3A1563609451&licenseKey=FDXL1Y2811&machineId=c5ec68a6-6e17-439f-b6fd-d965dda1b541&productCode=II&productFamilyId=II&salt=1713017276076&secure=false&userName=&version=2022300
    • header:Access-Encoding: gzip
      {
          "buildDate": "20221129",
          "buildNumber": "2022.3.3 Build IU-223.8836.41",
          "clientVersion": "13",
          "hostName": "",
          "licenseHash": "41472961/0:1563609451",
          "licenseKey": "FDXL1Y2811",
          //C:\Users\LYM\AppData\Roaming\JetBrains\PermanentUserId, 就是从这里获取的
          "machineId": "c5ec68a6-6e17-439f-b6fd-d965dda1b541",
          "productCode": "II",
          "productFamilyId": "II",
          //对同一个激活码,只改变salt--当前时间戳ms
          "salt": "1713017276076",
          "secure": "false",
          "userName": "",
          "version": "2022300"
      }
      

总结

  • 只需要一个合法key:需要在本地校验成功
  • 步骤:关闭网络,输入key,OK,重新联网
    • 不要打开license管理页,会立刻请求validateKey
    • 我试过,几个小时都没事
    • 亦或者阻断该validateKey请求,可以用网络代理的方法或者物理机器的方法,也可以用ja-netfilter一样的javaagent方法
  • 一种取巧的方式,JetBrains的IDE都有设置proxy功能,随便设个不存在的即可
  • 关于ja-netfilter:基本所有有的配置都一样,但是我是不太明白为什么还需要其他插件,感觉只需要plugins-url拦截validateKey请求
    • 关于激活码:他们好像都是自己出来的,应该是知道256B、hash、metadata,但是我不知道。。。

激活过程总结

  • 本地验证Key:
    • 格式正确:{LicenseId}-{LicenseJSON}-{256B}-{LicenseCert}
      • LicenseId和LicenseJSON必须用-连接着
    • 内容完整性(摘要)
      • 比如FDXL1Y2811是合法key,修改了LicenseJSON中的paidUpTo,结果FDXL1Y2811报错Key is invalid
        • LicenseId和LicenseJSON中的不同也不行
        • 即便使用ja-netfilter后,仍然报这个错
      • 可能与license的属性hash、metadata,以及key中的256B有关
      • 可能是内容完整性校验:签名、摘要
        • 可能是根据除hash、metadata外的数据进行特殊哈希
        • 因为在签名、摘要都没Debug到,可能用的是特殊的方法
      • 感觉paidUpTo没用
        • 非法Key:{"code":"GO","fallbackDate":"2025-08-01","paidUpTo":"2025-08-01","extended":false}
        • 合法Key:{"code":"GO","paidUpTo":"2024-05-11","extended":false}
          • 但是"licenseeType": "PERSONAL"
  • key合法后,才请求https://account.jetbrains.com/lservice/rpc/validateKey.action验证license

JaNetFilter

  • Result是在解密或者验签时匹配参数直接返回结果
    • 指数 = 65537 → 这是 公钥常用的 e 值(不是私钥 d!)
    • 所以这很可能是 验签(signature verification),而不是解密!
  • Arg是替换加密或者验签的参数
    • e=3 是另一个常见的小公钥指数(虽然不安全,但历史上用过)
    • 攻击者可能预先用 e=3 签名了一个 license
    • 但 IDEA 代码里写死了用 e=65537 验签
    • 所以插件把 65537 临时替换成 3
    • 这个不太清楚怎么回事,好像用的基本都是Result

✅ 正确结论

插件类型 作用时机 操作 在 IDEA 授权中的典型用途
ResultFilter / ResultTransformer modPow 开始执行时 匹配 (base, exponent, modulus) 参数 → 直接返回预设结果 验签或解密时,伪造合法 license 明文(最常用)
ArgsFilter / ArgsTransformer modPow 开始执行时 匹配 (exponent, modulus) → 替换为新的 (exponent', modulus') 较少用,可用于让程序用攻击者控制的密钥去解密/验签

🔍 详细解释(结合 IDEA 场景)

1. ResultFilter:直接返回结果(主流破解方式)
  • 触发点:IDEA 调用 ciphertext.modPow(privateKeyD, modulusN)(解密 license)
  • 插件行为
  • 检查 (ciphertext, privateKeyD, modulusN) 是否匹配规则
  • 如果匹配 → 不计算,直接返回 "{"licensedTo":"HACKER"}"
  • 效果
  • 即使 ciphertext 是乱码或用错误密钥加密的,
  • IDEA 也拿到了“看起来合法”的明文,激活成功。
  • 这就是为什么破解版 IDEA 能离线激活的核心原因

📌 重点:它劫持的是“解密结果”或“验签结果”,不是网络响应


2. ArgsFilter:替换参数(较少见,但可行)
  • 触发点:同样在 modPow 调用时
  • 插件行为
  • 检查 (privateKeyD, modulusN) 是否匹配(比如 JetBrains 的私钥)
  • 如果匹配 → 把 privateKeyDmodulusN 替换成攻击者自己的 (d_fake, n_fake)
  • 然后 IDEA 实际执行:ciphertext^d_fake mod n_fake
  • 前提
  • 攻击者必须提前用 (d_fake, n_fake) 加密好 license 明文,使得结果正好是合法内容。
  • 缺点
  • 需要控制模数 n,而 IDEA 的 n 是固定的,难以匹配
  • 更复杂,容易出错

📌 所以现实中 ResultFilter 更简单、更常用


🧪 类比理解

场景 正常流程 ResultFilter 干的事 ArgsFilter 干的事
考试答题 你计算 2+3=? 监考老师看你写“2+3”,直接给你卷面写“5” 监考老师把题目改成“1+4”,让你算
IDEA 解密 用私钥解密密文 看到你要解密,直接塞给你明文 把你的私钥换成我的私钥,让你用我的钥匙开锁

💡 补充:验签 vs 解密

  • 验签signature^e mod n → 得到 hash,对比原文 hash
    → 这里 e 是公钥,插件可匹配 (signature, e, n)
  • 解密ciphertext^d mod n → 得到明文
    → 这里 d 是私钥,插件匹配 (ciphertext, d, n)

ResultFilter 对两者都适用,只要三元组匹配,就返回你想要的结果。


如果你看到某个破解方案只用了 ResultTransformer,那基本可以确定:
👉 它是在 IDEA 本地验证 license 时,直接返回了伪造的授权信息,跳过了所有密码学计算。