问题
Proof key validator always returns invalid proof key.
I am referring to https://github.com/Microsoft/Office-Online-Test-Tools-and-Documentation/blob/master/samples/java/ProofKeyTester.java
@GET
@Path("/{file_id}")
@Produces(APPLICATION_JSON)
public Response checkFileInfo(@PathParam("file_id") String fileId, @QueryParam("access_token") String accessToken, @Context HttpHeaders httpHeaders, @Context HttpServletRequest request) {
try {
String proof = httpHeaders.getRequestHeader("X-WOPI-Proof") != null ? httpHeaders.getRequestHeader("X-WOPI-Proof").get(0) : null;
String proofOld = httpHeaders.getRequestHeader("X-WOPI-ProofOld") != null ? httpHeaders.getRequestHeader("X-WOPI-ProofOld").get(0) : null;
String wopiTimeStamp = httpHeaders.getRequestHeader("X-WOPI-TimeStamp") != null ? httpHeaders.getRequestHeader("X-WOPI-TimeStamp").get(0) : null;
String urlSrc = request.getRequestURL().toString();
String replacedStr = HTTP.matcher(urlSrc).replaceAll("https");
validateProofKey(proof, proofOld, wopiTimeStamp, replacedStr, accessToken);
}
private void validateProofKey(String proof, String proofOld, String timeStamp, String urlSrc, String accessToken) throws Exception {
LOGGER.info("verifying proof key");
ProofKeyManager proofKeyManager = getBean(ProofKeyManager.class);
String url = urlSrc + (urlSrc.contains(".wopitest") ? "?TESTCATEGORY=OFFICEONLINE&ACCESS_TOKEN=" : "?ACCESS_TOKEN=") + accessToken;
byte[] expectedProof = proofKeyManager.getExpectedProofBytes(url, accessToken, timeStamp);
WopiDiscovery wopiDiscovery = getBean(WopiDiscoveryProcessService.class).getWopiDiscoveryData();
String modulus = wopiDiscovery.getProofKey().getModulus();
String exponent = wopiDiscovery.getProofKey().getExponent();
String oldModulus = wopiDiscovery.getProofKey().getOldmodulus();
String oldExponent = wopiDiscovery.getProofKey().getOldexponent();
boolean validScenario = proofKeyManager.verifyProofKey(modulus, exponent, proof, expectedProof);
boolean validScenarioWithOld = proofKeyManager.verifyProofKey(modulus, exponent, proofOld, expectedProof);
boolean oldPK = proofKeyManager.verifyProofKey(oldModulus, oldExponent, proof, expectedProof);
if (proofKeyManager.verifyProofKey(modulus, exponent, proof, expectedProof) || proofKeyManager.verifyProofKey(modulus, exponent, proofOld, expectedProof) || proofKeyManager.verifyProofKey(oldModulus, oldExponent, proof, expectedProof)) {
LOGGER.info("proof key is valid");
} else {
LOGGER.error("proof key is not valid");
//throw new Exception("Invalid proof key");
}
}
If the request is generated by Office Online it should log "proof key is valid". But even in a valid case, it is logging "proof key is not valid".
回答1:
I can't directly answer this question, but I recently had the same problem implementing proof key validation in PHP. There were quite a few things I was doing incorrectly as a result of either not reading the docs properly, or the docs not specifying something. Ended up resolving it by translating the example tests in your linked github repository into PHP. The two main issues I had were:
Creating the public key from the modulus and exponent The given modulus and exponent in the discovery process is base64 encoded binary, which represents a large decimal number. You need to base64 decode, then convert to hex, then convert to decimal. Depending on your language/system you'll likely need some wrapper library around the decimal because it can be too large to fit in an
int
ordouble
.Encoding the numbers for the expected proof You need to get the length of the access token and url, then encode them. I used the php function
pack('J', $number)
for this.
You also need to encode the timestamp, for which I used pack('N', $number)
, calculate the length of it, and then encode the length using the above method.
In the end, it was a lot of trial end error. I cloned the example repository and ran the python validation tests, printing out different values along the way (eg. modulus, exponent, length of access token, url, timestamp, and what they encode to) and compare that to what my code was outputting.
Not a perfect answer, but this was a difficult process so hopefully can point people in the right direction.
来源:https://stackoverflow.com/questions/57568697/proof-key-validation-always-fails