【发布时间】:2020-05-11 10:22:46
【问题描述】:
我正在尝试在 URL 中集成需要签名查询参数的 Apple Map Web Snapshot。我能够从 NPM 成功地生成和验证 JWA 包中的 ES256 签名,但不能在 Java 中。请帮助我找到等效的库来生成有效的签名,我在 Java 中尝试了几个 JWA 库。
// Required modules.
const { readFileSync } = require("fs");
const { sign } = require("jwa")("ES256");
/* Read your private key from the file system. (Never add your private key
* in code or in source control. Always keep it secure.)
*/
const privateKey = readFileSync("[file_system_path]");
// Replace the team ID and key ID values with your actual values.
const teamId = "[team ID]";
const keyId = "[key ID]";
// Creates the signature string and returns the full Snapshot request URL including the signature.
function sign(params) {
const snapshotPath = `/api/v1/snapshot?${params}`;
const completePath = `${snapshotPath}&teamId=${teamId}&keyId=${keyId}`;
const signature = sign(completePath, privateKey);
// In this example, the jwa module returns the signature as a Base64 URL-encoded string.
// Append the signature to the end of the request URL, and return.
return `${completePath}&signature=${signature}`;
}
// Call the sign function with a simple map request.
sign("center=apple+park")
// The return value expected is: "/api/v1/snapshot?center=apple+park&teamId=[team ID]&keyId=[key ID]&signature=[base64_url_encoded_signature]"
Apache CXF - 此库在节点中生成类似于 JWA 模块但未能通过身份验证。
String teamId = [Team Id];
String keyId = [Key id];
String privateKey = [private key path];
String privateKeyContent = getKeyFileContent(privateKey);
String API_VERSION_PATH = "/api/v1/snapshot?";
String param = [QueryParam];
//example -> param = "center=[city,country or lat,lang]&size=90x90&lang=en&radius=2";
String params = param + "&teamId="+ teamId + "&keyId=" + keyId;
String payload = API_VERSION_PATH + params;
PrivateKey key = KeyFactory.getInstance("EC").generatePrivate(new PKCS8EncodedKeySpec(
Base64.decodeBase64(privateKeyContent)));
JwsCompactProducer compactProducer = new JwsCompactProducer(payload);
compactProducer.getJwsHeaders().setSignatureAlgorithm(SignatureAlgorithm.ES256);
//compactProducer.getJwsHeaders().setKeyId(keyId);
compactProducer.signWith(key);
String signed = compactProducer.getEncodedSignature();
String encodedSignature = new String(Base64.encodeBase64URLSafe(compactProducer.getEncodedSignature().getBytes()));
System.out.println(SNAPSHOT_API_PATH + payload + "&signature=" + signed);
JJWT - 这个库生成大签名,然后在节点模块中生成签名。
String signed = new String(Base64.encodeBase64URLSafe(Jwts.builder().setPayload(payload)
.signWith(io.jsonwebtoken.SignatureAlgorithm.ES256, key).compact().getBytes()));
System.out.println(SNAPSHOT_API_PATH + payload + "&signature=" + signed);
样本输出签名
compactProducer.getEncodedSignature() signed --> qQ5G9_lwGJ9w158FVSmtPx_iH43xlg2_gx9BlHEJbER73xpAeIHtDRnT8wnveH_UEPxNe7Zgv4csJ48Oiq-ZIQ
Base64.encodeBase64URLSafe(signature) --> cVE1RzlfbHdHSjl3MTU4RlZTbXRQeF9pSDQzeGxnMl9neDlCbEhFSmJFUjczeHBBZUlIdERSblQ4d252ZUhfVUVQeE5lN1pndjRjc0o0OE9pcS1aSVE
JJWT signed -> ZXlKaGJHY2lPaUpGVXpJMU5pSjkuTDJGd2FTOTJNUzl6Ym1Gd2MyaHZkRDlqWlc1MFpYSTlRM1Z3WlhKMGFXNXZMRlZUUVNaMFpXRnRTV1E5V0ZaWU5GWlhSbEZUTXlaclpYbEpaRDFWUVRWTlNGWlhWMWhMLlExUEtoeGwzSjFoVWVUWGtmeXRLckliYm5zeDdZem5lZVpxTVc4WkJOVU9uLVlYeFhyTExVU05ZVTZCSG5Xc3FheFd3YVB5dlF0Yml4TVBSZGdjamJ3
【问题讨论】:
-
你能分享一下签名在apache cxf中的样子以及它的字节数组有多大?同样在您的第二种情况下,我假设库生成整个 JWS,因此签名部分位于第二个点之后。
-
compactProducer.getEncodedSignature()签署 - > qQ5G9_lwGJ9w158FVSmtPx_iH43xlg2_gx9BlHEJbER73xpAeIHtDRnT8wnveH_UEPxNe7Zgv4csJ48Oiq-ZIQ Base64.encodeBase64URLSafe(签名) - > cVE1RzlfbHdHSjl3MTU4RlZTbXRQeF9pSDQzeGxnMl9neDlCbEhFSmJFUjczeHBBZUlIdERSblQ4d252ZUhfVUVQeE5lN1pndjRjc0o0OE9pcS1aSVE JJWT签署 - > ZXlKaGJHY2lPaUpGVXpJMU5pSjkuTDJGd2FTOTJNUzl6Ym1Gd2MyaHZkRDlqWlc1MFpYSTlRM1Z3WlhKMGFXNXZMRlZUUVNaMFpXRnRTV1E5V0ZaWU5GWlhSbEZUTXlaclpYbEpaRDFWUVRWTlNGWlhWMWhMLlExUEtoeGwzSjFoVWVUWGtmeXRLckliYm5zeDdZem5lZVpxTVc4WkJOVU9uLVlYeFhyTExVU05ZVTZCSG5Xc3FheFd3YVB5dlF0Yml4TVBSZGdjamJ3 跨度>
标签: java cryptography jwt mapkit cxf