{"record":{"id":"6341552e477062bd","repo":"binarywang/WxJava","slug":"apisignaturersaprivatekeysn","errorCode":null,"errorMessage":"ApiSignatureRsaPrivateKeySn不能为空，请检查配置","messagePattern":"ApiSignatureRsaPrivateKeySn不能为空，请检查配置","errorType":"exception","errorClass":"SecurityException","httpStatus":null,"severity":"error","filePath":"weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java","lineNumber":949,"sourceCode":"   * @param timestamp 签名时的时间戳\n   * @param postData  加密后的请求 POST 数据（JSON 字符串）\n   * @return 拼接好的待签名串\n   * @see <a href=\"https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/getting_started/api_signature.html\">微信服务端API签名指南</a>\n   */\n  static String buildSignaturePayload(String urlPath, String appId, long timestamp, String postData) {\n    return urlPath + \"\\n\" + appId + \"\\n\" + timestamp + \"\\n\" + postData;\n  }\n\n  @Override\n  public String postWithSignature(String url, JsonObject jsonObject) throws WxErrorException {\n    long timestamp = System.currentTimeMillis() / 1000;\n    String appId = this.getWxMaConfig().getWechatMpAppid();\n    String rndStr = UUID.randomUUID().toString().replace(\"-\", \"\").substring(0, 30);\n    String aesKey = this.getWxMaConfig().getApiSignatureAesKey();\n    String aesKeySn = this.getWxMaConfig().getApiSignatureAesKeySn();\n    String rsaKeySn = this.getWxMaConfig().getApiSignatureRsaPrivateKeySn();\n    if (rsaKeySn == null || rsaKeySn.isEmpty()) {\n      throw new SecurityException(\"ApiSignatureRsaPrivateKeySn不能为空，请检查配置\");\n    }\n\n    jsonObject.addProperty(\"_n\", rndStr);\n    jsonObject.addProperty(\"_appid\", appId);\n    jsonObject.addProperty(\"_timestamp\", timestamp);\n\n    String plainText = jsonObject.toString();\n    log.debug(\"URL:{}加密前请求数据:{}\", url, plainText);\n    String urlPath;\n    if (url.contains(\"?\")) {\n      urlPath = url.substring(0, url.indexOf(\"?\"));\n    } else {\n      urlPath = url;\n    }\n    String aad = urlPath + \"|\" + appId + \"|\" + timestamp + \"|\" + aesKeySn;\n    byte[] realKey;\n    try {\n      realKey = Base64.getDecoder().decode(aesKey);","sourceCodeStart":931,"sourceCodeEnd":967,"githubUrl":"https://github.com/binarywang/WxJava/blob/1c43293a3c2c9d7e91304b6d037fb017f680d0c6/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java#L931-L967","documentation":"Thrown as SecurityException when ApiSignatureRsaPrivateKeySn is null or empty in postWithSignature(). This serial number identifies the RSA key pair used for the WeChat API signature (加密网络通道) feature that signs outgoing requests with RSA-PSS. The serial number must be registered with WeChat when uploading the public key.","triggerScenarios":"Calling postWithSignature(url, jsonObject) without having configured apiSignatureRsaPrivateKeySn in the WxMaConfig object.","commonSituations":"API signature feature not fully configured; serial number field not set after key generation; new feature adoption without completing the RSA key registration with WeChat platform.","solutions":["Set the RSA key serial number: wxMaConfig.setApiSignatureRsaPrivateKeySn(serialNumber)","Obtain the serial number from the WeChat platform when uploading your RSA public key via the certificate management API","Verify all four API signature fields are set: aesKey, aesKeySn, rsaPrivateKeySn, rsaPrivateKey"],"exampleFix":"// before\nwxMaConfig.setApiSignatureRsaPrivateKeySn(null);\n\n// after\nwxMaConfig.setApiSignatureRsaPrivateKeySn(\"your-rsa-key-serial-number\");","handlingStrategy":"validation","validationCode":"// Validate API signature config before calling postWithSignature\nString rsaKeySn = wxMaConfig.getApiSignatureRsaPrivateKeySn();\nif (rsaKeySn == null || rsaKeySn.isEmpty()) {\n  throw new IllegalStateException(\"ApiSignatureRsaPrivateKeySn is required for postWithSignature\");\n}\nservice.postWithSignature(url, jsonObject);","typeGuard":"private static boolean isApiSignatureConfigReady(WxMaConfig config) {\n  return config.getApiSignatureRsaPrivateKeySn() != null\n      && !config.getApiSignatureRsaPrivateKeySn().isEmpty();\n}","tryCatchPattern":"try {\n  service.postWithSignature(url, jsonObject);\n} catch (SecurityException e) {\n  if (e.getMessage().contains(\"RsaPrivateKeySn\")) {\n    log.error(\"API signature RSA serial number not configured\");\n    // configure it dynamically or fall back to non-signed API\n  } else {\n    throw e;\n  }\n}","preventionTips":["Set all four API signature fields at config time: aesKey, aesKeySn, rsaPrivateKeySn, rsaPrivateKey","Validate configuration completeness in a startup health check before using postWithSignature","Document the full API signature setup process including RSA key upload to WeChat platform"],"tags":["configuration","miniapp","security","api-signature"],"backgroundTag":null,"analyzedSha":"1c43293a3c2c9d7e91304b6d037fb017f680d0c6","analyzedAt":"2026-08-14T02:29:11.060Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}